分析
这场比赛较难的一道题。我们可以根据坐标建一根线段树,然后在线段树上二分。这样就可以做到 ,而并不是题解的
。没有太大思维量,根据题意把线段树建出来,然后对于每一个节点模拟一下就好了。主要还是考察了代码能力吧。要注意是按输入顺序来考虑的,而不是坐标的从左向右。
代码
#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;
}
京公网安备 11010502036488号