九野的博客,转载请注明出处: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; }