bzoj 1503 郁闷的出纳员
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1503 郁闷的出纳员相关的知识,希望对你有一定的参考价值。
平衡树维护。
treap还是引用版的好写,自带大代码量写非引用版的估计要300行+。
删除的时候各种pushup不太好理解。
注意刚来就走的员工不算在最后一问里。
删除一个值要减去这个值的所有员工数,直接减一wa半天。
1 #include<cstring> 2 #include<cstdio> 3 #include<algorithm> 4 #include<iostream> 5 #include<cstdlib> 6 using namespace std; 7 const int dian=100005; 8 int aa[1000005]; 9 int ky[dian],pr[dian],ch[dian][3],siz[dian],num[dian]; 10 char flag[10]; 11 int n,m,a; 12 int len,cnt,root,summ; 13 int rd(){ 14 int xx=rand()%1000; 15 int yy=rand()%1000; 16 int zz=xx*1000+yy+1; 17 zz=zz%len+1; 18 int lala=aa[zz]; 19 aa[zz]=aa[len]; 20 len--; 21 return lala; 22 } 23 void pushup(int x){ 24 siz[x]=siz[max(0,ch[x][0])]+siz[max(0,ch[x][1])]+num[x]; 25 } 26 void rotate(int &k,int ok){ 27 int t=ch[k][ok]; 28 ch[k][ok]=ch[t][ok^1]; 29 ch[t][ok^1]=k; 30 pushup(k),pushup(t); 31 k=t; 32 } 33 void insert(int &k,int tkey){ 34 if(k==-1){ 35 k=++cnt; 36 ky[k]=tkey; 37 pr[k]=rd(); 38 ch[k][0]=-1; 39 ch[k][1]=-1; 40 num[k]=1; 41 siz[k]=1; 42 } 43 else{ 44 siz[k]++; 45 if(tkey==ky[k]) 46 num[k]++; 47 else if(tkey<ky[k]){ 48 insert(ch[k][0],tkey); 49 if(pr[ch[k][0]]<pr[k]) 50 rotate(k,0); 51 } 52 else{ 53 insert(ch[k][1],tkey); 54 if(pr[ch[k][1]<pr[k]]) 55 rotate(k,1); 56 } 57 } 58 } 59 void del(int &k){ 60 if(ch[k][0]==-1&&ch[k][1]==-1) 61 k=-1; 62 else if(ch[k][0]==-1) 63 k=ch[k][1]; 64 else if(ch[k][1]==-1) 65 k=ch[k][0]; 66 else if(pr[ch[k][0]]<pr[ch[k][1]]){ 67 rotate(k,0); 68 del(ch[k][1]); 69 pushup(k); 70 } 71 else{ 72 rotate(k,1); 73 del(ch[k][0]); 74 pushup(k); 75 } 76 } 77 void add(int k,int x){ 78 if(k==-1) 79 return; 80 ky[k]+=x; 81 add(ch[k][0],x); 82 add(ch[k][1],x); 83 } 84 void dec(int &k,int x){ 85 while(ky[k]-x<m&&k!=-1){ 86 summ+=num[k]; 87 del(k); 88 } 89 if(k==-1) 90 return; 91 ky[k]-=x; 92 dec(ch[k][0],x); 93 dec(ch[k][1],x); 94 pushup(k); 95 } 96 int find(int k,int rank){ 97 if(rank-siz[max(0,ch[k][1])]>=1&&rank-siz[max(0,ch[k][1])]<=num[k]) 98 return ky[k]; 99 else if(siz[max(0,ch[k][1])]>=rank) 100 return find(ch[k][1],rank); 101 else 102 return find(ch[k][0],rank-siz[max(ch[k][1],0)]-num[k]); 103 } 104 int main(){ 105 for(int i=1;i<=1000000;i++) 106 aa[i]=i; 107 len=1000000; 108 cnt=0; 109 root=-1; 110 summ=0; 111 srand(1600158127); 112 scanf("%d%d",&n,&m); 113 for(int i=1;i<=n;i++){ 114 scanf("%s%d",flag,&a); 115 if(flag[0]==‘I‘){ 116 if(a<m) 117 continue; 118 insert(root,a); 119 } 120 else if(flag[0]==‘A‘) 121 add(root,a); 122 else if(flag[0]==‘S‘) 123 dec(root,a); 124 else{ 125 if(a>siz[root]) 126 printf("-1\n"); 127 else 128 printf("%d\n",find(root,a)); 129 } 130 } 131 printf("%d\n",summ); 132 return 0; 133 }
为什么我写得这么长!
以上是关于bzoj 1503 郁闷的出纳员的主要内容,如果未能解决你的问题,请参考以下文章