hdu 5493 Queue treap实现将元素快速插入到第i个位置
input
T 1<=T<=1000
n 1<=n<=100000
h1 k1
h2 k2
... ...
hn kn
1<=hi<=1e9 0<=ki<=n-1
sum(n)<=1e6
hi!=hj(i!=j)
output
hi指第i个人的身高,ki指这个人前面或者后面比他高的人数
Case #cas: 输出可能的最小序列,没有输出impossible
做法:将所有人按身高排序,从高到低插入数组中,则插入到第i个人时,数组里所有人都比他高,用treap实现,每个人有两个位置可以插入,每次插入到小的位置
1 #include <cstdio> 2 #include <queue> 3 #include <cstring> 4 #include <iostream> 5 #include <cstdlib> 6 #include <algorithm> 7 #include <vector> 8 #include <map> 9 #include <set> 10 #include <ctime> 11 #include <cmath> 12 #include <cctype> 13 #define MAX 100000 14 #define LL long long 15 int cas=1,T,first,a[MAX+10][2]; 16 struct node 17 { 18 node*ch[2]; 19 int r,v,sz; 20 void maintain() { sz=(ch[0]?ch[0]->sz:0)+(ch[1]?ch[1]->sz:0)+1; } 21 }; 22 void rotate(node* &o,int d) 23 { 24 node*k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o; 25 o->maintain();k->maintain();o=k; 26 } 27 void insert(node* &o,int pos,int &x) 28 { 29 if(o==NULL) 30 { 31 o=new node(); 32 o->ch[0]=o->ch[1]=NULL; 33 o->v=x;o->r=rand(); 34 o->sz=1; 35 return; 36 } 37 o->sz++; //易错,旋转时可能没旋转到该结点,导致没更新,所以在插入后要++ 38 int d; 39 if(pos <= (o->ch[0]?o->ch[0]->sz:0)) d=0; 40 else { d=1;pos -= (o->ch[0]?o->ch[0]->sz:0)+1; } 41 insert(o->ch[d],pos,x); 42 if(o->ch[d]->r > o->r) rotate(o,d^1); 43 } 44 void read(node*u) 45 { 46 if(u==NULL) return; 47 read(u->ch[0]); 48 printf(" %d",u->v); 49 read(u->ch[1]); 50 delete u; 51 } 52 int cmp(const void*a,const void*b) { return *(int*)b-*(int*)a; } 53 int main() 54 { 55 //freopen("/home/user/桌面/in","r",stdin); 56 scanf("%d",&T); 57 int n; 58 while(T--) 59 { 60 scanf("%d",&n); 61 for(int i=1;i<=n;i++) scanf("%d%d",&a[i][0],&a[i][1]); 62 qsort(a+1,n,sizeof(a[0]),cmp); 63 int i; 64 node *root=NULL; 65 for(i=1;i<=n;i++) 66 { 67 if(a[i][1]>=i) break; 68 int pos=std::min(a[i][1],i-1-a[i][1]); 69 insert(root,pos,a[i][0]); 70 } 71 printf("Case #%d:",cas++); 72 if(i<=n) { puts(" impossible");continue; } 73 read(root); 74 printf("\n"); 75 } 76 //printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC); 77 return 0; 78 }