题意:给定一个队列,有n个人,每个人按顺序插入到队列中的某个位置,问最后的队列序列
解题思路:无力吐槽自己的智商了,神题,完全利用了线段树的性质进行搜索
解题代码:
1 // File Name: poj2182.c 2 // Author: darkdream 3 // Created Time: 2013年07月29日 星期一 22时05分45秒 4 5 #include<stdio.h> 6 #include<string.h> 7 #include<stdlib.h> 8 #include<time.h> 9 #include<math.h> 10 #include<ctype.h> 11 #define MAXN 200005 12 struct node 13 { 14 int left ,right ,mid ; 15 int num; 16 }tree[MAXN* 4]; 17 int a[MAXN]; 18 int R(int c) 19 { 20 return 2 * c+1; 21 } 22 int L(int c) 23 { 24 return 2 * c; 25 } 26 void up(int c) 27 { 28 tree[c].num = tree[L(c)].num + tree[R(c)].num ; 29 } 30 void build(int c, int p ,int v) 31 { 32 tree[c].left = p; 33 tree[c].right = v ; 34 tree[c].mid = (p + v )/2; 35 tree[c].num = v-p + 1 ; 36 if(p == v ) 37 { 38 return; 39 } 40 build(L(c),p,tree[c].mid); 41 build(R(c),tree[c].mid + 1, v); 42 } 43 int ok= 0 ; 44 void update( int c, int p ) 45 { 46 tree[c].num --; 47 if(tree[c].left == tree[c].right) 48 { 49 ok = tree[c].left; 50 return; 51 } 52 if(p > tree[L(c)].num) update(R(c),p - tree[L(c)].num); 53 else update(L(c),p); 54 } 55 int tsum = 0 ; 56 void getsum (int c, int p , int v ) 57 { 58 if(p <= tree[c].left && v >= tree[c].right) 59 { 60 tsum += tree[c].num; 61 return ; 62 } 63 if(v <= tree[c].mid) getsum(L(c),p,v); 64 else if(p > tree[c].mid) getsum(R(c),p,v); 65 else 66 { 67 getsum(L(c),p,tree[c].mid); 68 getsum(R(c),tree[c].mid+1,v); 69 } 70 } 71 int b[MAXN]; 72 int c[MAXN]; 73 int main(){ 74 75 76 //freopen("/home/plac/problem/input.txt","r",stdin); 77 //freopen("/home/plac/problem/output.txt","w",stdout); 78 int n; 79 while(scanf("%d",&n) != EOF) 80 { 81 for(int i = 1;i <= n; i ++) 82 { 83 scanf("%d %d",&a[i],&c[i]); 84 a[i] = a[i] + 1; 85 } 86 b[a[n]] = c[n]; 87 build(1,1,n); 88 update(1,a[n]); 89 for(int i= n -1; i >= 1; i -- ) 90 { 91 ok = 0; 92 //printf("%d ",tsum); 93 update(1,a[i]); 94 b[ok] = c[i]; 95 } 96 for(int i = 1;i <= n;i ++) 97 printf("%d ",b[i]); 98 printf(" "); 99 } 100 return 0 ; 101 }