虽然说是疯狂训练吧,但是也没写多少题,就把伸展树的操作熟悉了一下,ac了5个题目。
一整天没啥可吐槽的,除了昨天在机房打游戏的某位朋友翻车后和教练谈了谈心2333
说题吧。。
1.BZOJ1208 HNOI2004 宠物收养所
这个题思路很简单,当做模板题打,在模板题中也算是简单的了,涉及操作:前驱,后继,插入,删除。。输入进来就插入,领养走就删除,并没有什么可说的。加上一个标记表示现在树上表示的是宠物还是人。
另外听说可以用set做,但是我并不会set(???set都不会吃屎吧)。
CODE:
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int n,size,rt,kind,t1,t2; 5 long long ans; 6 int tr[80001][2],num[80001],fa[80001]; 7 void rotate(int x,int &k) 8 { 9 int y=fa[x],z=fa[y],l,r; 10 if(tr[y][0]==x)l=0;else l=1;r=l^1; 11 if(y==k)k=x; 12 else{if(tr[z][0]==y)tr[z][0]=x;else tr[z][1]=x;} 13 fa[x]=z;fa[y]=x;fa[tr[x][r]]=y; 14 tr[y][l]=tr[x][r];tr[x][r]=y; 15 } 16 void splay(int x,int &k) 17 { 18 int y,z; 19 while(x!=k) 20 { 21 y=fa[x],z=fa[y]; 22 if(y!=k) 23 { 24 if((tr[y][0]==x)^(tr[z][0]==y))rotate(x,k); 25 else rotate(y,k); 26 } 27 rotate(x,k); 28 } 29 } 30 void ins(int &k,int x,int last) 31 { 32 if(k==0){size++;k=size;num[k]=x;fa[k]=last;splay(k,rt);return;} 33 if(x<num[k])ins(tr[k][0],x,k);else ins(tr[k][1],x,k); 34 } 35 void del(int x) 36 { 37 splay(x,rt); 38 if(tr[x][0]*tr[x][1]==0) 39 {rt=tr[x][0]+tr[x][1];} 40 else 41 { 42 int k=tr[x][1]; 43 while(tr[k][0])k=tr[k][0]; 44 tr[k][0]=tr[x][0];fa[tr[x][0]]=k; 45 rt=tr[x][1]; 46 } 47 fa[rt]=0; 48 } 49 void ask_before(int k,int x) 50 { 51 if(k==0)return; 52 if(num[k]<=x){t1=k;ask_before(tr[k][1],x);} 53 else ask_before(tr[k][0],x); 54 } 55 void ask_after(int k,int x) 56 { 57 if(k==0)return; 58 if(num[k]>=x){t2=k;ask_after(tr[k][0],x);} 59 else ask_after(tr[k][1],x); 60 } 61 62 int main() 63 { 64 scanf("%d",&n); 65 int f,x; 66 for(int i=1;i<=n;i++) 67 { 68 scanf("%d%d",&f,&x); 69 if(!rt){kind=f;ins(rt,x,0);} 70 else if(kind==f){ins(rt,x,0);} 71 else 72 { 73 t1=t2=-1; 74 ask_before(rt,x);ask_after(rt,x); 75 if(t1==-1){ans+=num[t2]-x;ans%=1000000;del(t2);} 76 else if(t2==-1){ans+=x-num[t1];ans%=1000000;del(t1);} 77 else 78 { 79 if(x-num[t1]>num[t2]-x) {ans+=num[t2]-x;ans%=1000000;del(t2);} 80 else{ans+=x-num[t1];ans%=1000000;del(t1);} 81 } 82 } 83 } 84 cout<<ans<<endl; 85 return 0; 86 }