[JSOI2008]最大数
平衡树模板题。。fhq treap貌似容易写一些?
注意输入数据有负数。。所以先把0号空节点设为-int_max就行。。
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 #include <map> 7 #include <string> 8 #include <vector> 9 #include <stack> 10 using namespace std; 11 12 const int N=300000; 13 14 int sz[N],v[N],ch[N][2],mx[N],root,tot; 15 int newNode(int x){ 16 tot++; 17 v[tot]=x; 18 sz[tot]=1; 19 mx[tot]=x; 20 return tot; 21 } 22 void up(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;mx[x]=max(v[x],max(mx[ch[x][0]],mx[ch[x][1]]));} 23 24 int merge(int a,int b){ 25 if(!a||!b)return a|b; 26 if(rand()%(sz[a]+sz[b])<sz[a]){ 27 ch[a][1]=merge(ch[a][1],b); 28 up(a); 29 return a; 30 }else{ 31 ch[b][0]=merge(a,ch[b][0]); 32 up(b); 33 return b; 34 } 35 } 36 37 typedef pair<int,int> sp; 38 sp split(int a,int k){ 39 if(!a)return sp(0,0); 40 sp s; 41 if(sz[ch[a][0]]>=k){ 42 s=split(ch[a][0],k); 43 ch[a][0]=s.second; 44 s.second=a; 45 up(a); 46 }else{ 47 s=split(ch[a][1],k-sz[ch[a][0]]-1); 48 ch[a][1]=s.first; 49 s.first=a; 50 up(a); 51 } 52 return s; 53 } 54 55 int m,d,t,x; 56 char str[10]; 57 int main(){ 58 mx[0]=v[0]=-0x3f3f3f3f; 59 srand(233); 60 scanf("%d%d",&m,&d); 61 while(m--){ 62 scanf("%s%d",str,&x); 63 if(str[0]=='Q'){ 64 sp s=split(root,tot-x); 65 printf("%d\n",t=mx[s.second]); 66 root=merge(s.first,s.second); 67 }else{ 68 root=merge(root,newNode((x+t)%d)); 69 } 70 } 71 }