分析
这场比赛较难的一道题。我们可以根据坐标建一根线段树,然后在线段树上二分。这样就可以做到 ,而并不是题解的 。没有太大思维量,根据题意把线段树建出来,然后对于每一个节点模拟一下就好了。主要还是考察了代码能力吧。要注意是按输入顺序来考虑的,而不是坐标的从左向右。
代码
#include<bits/stdc++.h> using namespace std; const int N = 1e6 + 10,inf = 0x3f3f3f3f,mod = 1e9 + 7; int read() { int x = 0,f = 0;char ch = getchar(); while(!isdigit(ch)) {if(ch == '-')f = 1;ch = getchar();} while(isdigit(ch)) {x = x * 10 + ch - '0';ch = getchar();} return f ? -x : x; } int mx[N],mi[N],n,B[N],h[N]; struct Node{int id,x,H;}P[N]; bool cmpx(Node a,Node b) {return a.x < b.x;} bool cmpid(Node a,Node b) {return a.id < b.id;} void build(int u,int l,int r) { if(l == r) {h[l] = mx[u] = P[l].H;mi[u] = l;return;} int mid = l + r >> 1; build(u<<1,l,mid);build(u<<1|1,mid+1,r); mx[u] = max(mx[u<<1|1],mx[u<<1]); if(h[mi[u<<1]] <= h[mi[u<<1|1]]) mi[u] = mi[u<<1]; else mi[u] = mi[u<<1|1]; } void update(int u,int l,int r,int pos,int k) { if(l == r) {h[l] = mx[u] = k;mi[u] = l;return;} int mid = l + r >> 1; if(pos <= mid) update(u<<1,l,mid,pos,k); else update(u<<1|1,mid+1,r,pos,k); mx[u] = max(mx[u<<1|1],mx[u<<1]); if(h[mi[u<<1]] <= h[mi[u<<1|1]]) mi[u] = mi[u<<1]; else mi[u] = mi[u<<1|1]; } int askmx(int u,int l,int r,int L,int R,int h) { int mid = l + r >> 1; if(L <= l && r <= R) { if(l == r) return mx[u] > h ? l : 0; if(mx[u<<1|1] > h) return askmx(u<<1|1,mid+1,r,L,R,h); else if(mx[u<<1] > h) return askmx(u<<1,l,mid,L,R,h); else return 0; } int ans = 0; if(mid < R) ans = askmx(u<<1|1,mid+1,r,L,R,h); if(ans == 0 && L <= mid) ans = askmx(u<<1,l,mid,L,R,h); return ans; } int askmi(int u,int l,int r,int L,int R) { if(l > R || r < L) return 0; if(L <= l && r <= R) return mi[u]; int mid = l + r >> 1; int posl = askmi(u<<1,l,mid,L,R); int posr = askmi(u<<1|1,mid+1,r,L,R); if(h[posl] <= h[posr]) return posl;else return posr; } int Id[N]; int main() { n = read(); for(int i = 1;i <= n;i++) { P[i].id = i;B[i] = P[i].x = read();P[i].H = read(); } h[0] = 0x3f3f3f3f; sort(B + 1,B + 1 + n); for(int i = 1;i <= n;i++) {P[i].x = lower_bound(B+1,B+1+n,P[i].x) - B;} sort(P + 1,P + 1 + n,cmpx); for(int i = 1;i <= n;i++) Id[P[i].id] = i; build(1,1,n); sort(P + 1,P + 1 + n,cmpid); for(int i = 1;i <= n;i++) { int pos = P[i].x,posmx = 0,posmi = 0; if(pos != 1) posmx = askmx(1,1,n,1,pos-1,h[P[i].x]); if(posmx) { update(1,1,n,posmx,h[P[i].x]); } posmx = 0; if(pos != n) { posmx = askmx(1,1,n,pos+1,n,h[P[i].x]); if(posmx == 0) posmi = askmi(1,1,n,pos+1,n); } if(posmi) { update(1,1,n,posmi,h[P[i].x]); } } for(int i = 1;i <= n;i++) { printf("%d ",h[Id[i]]); } printf("\n"); return 0; }