链接:http://poj.org/problem?id=1436
题意:排队买票,后来的可以插队
代码:
#include<cstdio>
#include<iostream>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn = 200010;
int space[maxn<<2];
int nn[maxn];
void pushup(int rt){
space[rt] = space[rt<<1] + space[rt<<1|1];
}
void build(int l,int r,int rt){
if(l==r){
space[rt] = 1;
return ;
}
int m = (l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
void update(int a,int b,int l,int r,int rt){
if(l==r){
space[rt] = 0;
nn[l]=b;
return ;
}
int m = (l + r) >> 1;
if(space[rt<<1]>=a)update(a , b , lson);
else update(a - space[rt<<1] , b , rson);
pushup(rt);
}
int main(){
int n;
while(~scanf("%d",&n)){
int a[maxn],b[maxn];
for(int i=0;i<n;i++){
scanf("%d%d",&a[i],&b[i]);
}
build(1,n,1);
for(int i=n-1;i>=0;i--)
update(a[i]+1,b[i],1,n,1);
printf("%d",nn[1]);
for(int i=2;i<=n;i++)
printf(" %d",nn[i]);
printf("\n");
}
return 0;
}
知道使用线段树做= =,但是看了半天却没啥思路。。悄悄看了眼题解~,上面写到从后往前更新,立马就有种豁然开朗的感觉啊!!然后发现是错觉。
不过大体的方向基本上也就能确定下来了。
在此处写一下对线段树的一些认识(说猜测应该比较实际。。)= =,就是我总是搞混的一些东西。。
----------------------------------------------------------------(胆小勿入)----------------------------------------------------------------
void update(int a,int b,int l,int r,int rt)对于每一组l,r,rt,那个数组(本题中的space)space[rt]表示的就是l~r的线段~~
if(l==r){
space[rt] = 0;
nn[l]=b;
return ;
} 当l==r时,l就是单点更新的那个点的下标
额。。也就这两个地方比较懵了。。先这样,慢慢理解。智商被压制,,没办法= =
23333333333333