http://poj.org/problem?id=2828
险过 3500+ms
第i个人入队 只影响后面的不会影响前面的 可以倒推 全初始化为1 第i个人去第k位置 由于是倒推,第k个位置为0,表示求k-1位置的时候不能算上k位置的人 根据区间和 求出区间第K值 就是第i个人要放的位置
1 #include <iostream> 2 #include<cstdio> 3 #include<string.h> 4 using namespace std; 5 #define N 200001 6 int s[N*4],d[N*2][2],po[N*2],j; 7 void build(int l,int r,int w) 8 { 9 if(l==r) 10 { 11 s[w] = 1; 12 return ; 13 } 14 int m = (l+r)/2; 15 build(l,m,2*w); 16 build(m+1,r,2*w+1); 17 } 18 void upset(int l,int r,int w) 19 { 20 if(l==r) 21 return ; 22 int m =(l+r)/2; 23 upset(l,m,2*w); 24 upset(m+1,r,2*w+1); 25 s[w] = s[w*2]+s[2*w+1]; 26 } 27 void add(int p,int da,int l,int r,int w) 28 { 29 if(l==r) 30 { 31 s[w] = 0; 32 po[l] = da; 33 return ; 34 } 35 int m= (l+r)/2; 36 if(p<=s[w*2]) 37 add(p,da,l,m,2*w); 38 else 39 add(p-s[w*2],da,m+1,r,2*w+1); 40 s[w] = s[2*w]+s[w*2+1]; 41 } 42 int main() 43 { 44 int n,i,k,m; 45 while(scanf("%d",&n)!=EOF) 46 { 47 j =0; 48 memset(po,0,sizeof(po)); 49 for(i = 1; i <= n ; i++) 50 scanf("%d%d", &d[i][0],&d[i][1]); 51 build(1,n,1); 52 upset(1,n,1); 53 for(i = n ; i >= 1; i--) 54 add(d[i][0]+1,d[i][1],1,n,1); 55 for(i = 1 ; i < n ; i++) 56 printf("%d ",po[i]); 57 printf("%d\n",po[n]); 58 } 59 return 0; 60 }