九野的博客,转载请注明出处:http://blog.csdn.net/acmmmm/article/details/11971839
题意:
n个人
n行:a,b 表示b这个人插队插在a位置
问最后队伍的顺序
思路:
从最后一个人开始,插队过程表示为:
把b放在第a个空位的位置
#include <cstdio>
#include <cstring>
#include <iostream>
#include <math.h>
#include <queue>
#define N 201000
#define M 2000100
#define inf64 0x7ffffff
#define inf 0x7ffffff
#define ll int
#define L(x) x<<1
#define R(x) x<<1|1
#define Mid(x,y) (x+y)>>1
using namespace std;
inline ll Min(ll a,ll b){return a>b?b:a;}
inline ll Max(ll a,ll b){return a>b?a:b;}
ll len,maxdeep,Query;
struct node{
int l,r;
ll sum,num;//sum表示每个人的编号,num表示这个区间剩下的空位
}tree[N*4];
void build(int l,int r,int id){
tree[id].l = l; tree[id].r = r;
tree[id].num = r-l+1;
if(l==r) return ;
int mid = Mid(l,r);
build(l,mid,L(id)); build(mid+1,r,R(id));
}
void updata_point(int pos,int id, ll data){//单点更新
if(tree[id].l == tree[id].r)
{
tree[id].num--;
tree[id].sum = data;
return ;
}
tree[id].num--;
if( tree[ L(id) ].num > pos) updata_point(pos,L(id),data);
else updata_point(pos-tree[L(id)].num,R(id),data);
}
ll query_point(int pos, int id){ //单点询问 sum
if(tree[id].l == pos && pos == tree[id].r)
return tree[id].sum ;
int mid = Mid(tree[id].l, tree[id].r);
if(pos <= mid) return query_point(pos, L(id));
else return query_point(pos, R(id));
}
struct quenode{
int a, b;
}qq[N];
int main(){
int n,a,b,i;
while(~scanf("%d",&n)){
build( 1, n, 1);
for(i=0;i<n;i++)
scanf("%d %d",&qq[i].a,&qq[i].b);
for(i=n-1;i>=0;i--)
{
updata_point( qq[i].a, 1, qq[i].b);
}
for(i=1;i<n;i++)printf("%d ",query_point(i,1));
printf("%d\n",query_point(i,1));
}
return 0;
}