想试下新找的板子,没想到交上去CE了。。懒得调。。以后有机会就改
/* 用type标记当前树上的是宠物还是人 每次求前驱后缀,删掉最近的那个点 */ #include<iostream> #include<cstring> #include<cstdio> #include<cmath> using namespace std; #define maxn 1000100 #define L ch[r][0] #define R ch[r][1] #define KT ch[ch[r][1]][0] struct Splay{ int pre[maxn],sz[maxn],ch[maxn][2],val[maxn],rt,tot; int flag; inline void newnode(int &r,int fa,int key){ r=++tot; L=R=0; pre[r]=fa; val[r]=key; sz[r]=1; sz[L]=sz[R]=0; } inline void pushup(int r){ sz[r]=1; if(L) sz[r]+=sz[L]; if(R) sz[r]+=sz[R]; } inline void init(){//加两个边界 rt=tot=flag=0; ch[rt][0]=ch[rt][1]=sz[rt]=pre[rt]=0; newnode(rt,0,-99999999); newnode(ch[rt][1],rt,9999999); memset(sz,0,sizeof sz); } inline void rotate(int x,int f) { int y=pre[x]; ch[y][!f] = ch[x][f]; pre[ ch[x][f] ] = y; pre[x] = pre[y]; if(pre[x]) ch[ pre[y] ][ ch[pre[y]][1] == y ] =x; ch[x][f] = y; pre[y] = x; pushup(y); } inline void splay(int x,int goal) { //将x旋转到goal的下面 while(pre[x] != goal) { if(pre[pre[x]] == goal) rotate(x , ch[pre[x]][0] == x); else { int y=pre[x],z=pre[y]; int f = (ch[z][0]==y); if(ch[y][f] == x) rotate(x,!f),rotate(x,f); else rotate(y,f),rotate(x,f); } } pushup(x); if(goal==0) rt=x; } inline void insert(int &r,int key,int fa){ if(!r){newnode(r,fa,key);splay(r,0);return;} else if(key<val[r]) insert(L,key,r); else insert(R,key,r); pushup(r); } inline int findkth(int r,int k){//找第k大的那个结点的值 if(k==sz[L]+1) {splay(r,0);return val[r];} else if(k<sz[L]+1) return findkth(L,k); else return findkth(R,k-sz[L]-1); } inline int find(int r,int key){//找键值为key的结点 if(!r) return 0;//不存在这个键值 else if(key==val[r]) return r; else if(key<val[r]) find(L,key); else find(R,key); } void remove(){ int t=rt; if(ch[rt][1]){//删掉根节点并以后缀作为根 rt=ch[rt][1]; splay(getmin(rt),0); ch[rt][0]=ch[t][0]; if(ch[rt][0]) pre[ch[rt][0]]=rt; } else rt=ch[rt][0]; pre[rt]=0; pushup(rt); } void findpre(int r,int key,int &ans){//找前驱结点(找值比key小的的最大的结点) if(!r) return; if(key>=val[r]) {ans=r;findpre(R,key,ans);} else findpre(L,key,ans); } void findsucc(int r,int key,int &ans){///找后继 if(!r) return; if(key<=val[r]) {ans=r;findsucc(L,key,ans);} else findsucc(R,key,ans); } inline int getmin(int r){while(L) r=L;return r;} inline int getmax(int r){while(R) r=R;return r;} inline void vist(int r){ if(r){ printf("结点%2d : 左儿子 %2d 右儿子 %2d val:%2d sz=%d ",r,L,R,val[r],sz[r]); vist(L); vist(R); } } void debug() { puts(""); vist(rt); puts(""); } }spt; int main(){ int n,a,b,ans; while(scanf("%d",&n)==1){ spt.init(); ans=0; for(int i=1;i<=n;i++){ scanf("%d%d",&a,&b); // spt.debug(); if(spt.sz[spt.rt]==2){ spt.flag=a; spt.insert(spt.rt,b,0); } else { if(spt.flag==a) spt.insert(spt.rt,b,0); else { int tmp1,tmp2; spt.findpre(spt.rt,b,tmp1); spt.findsucc(spt.rt,b,tmp2); if(abs(b-spt.val[tmp1])<=abs(b-spt.val[tmp2])){ ans+=abs(b-spt.val[tmp1]); spt.splay(tmp1,0); spt.remove(); } else { ans+=abs(b-spt.val[tmp2]); spt.splay(tmp2,0); spt.remove(); } } } // spt.debug(); } printf("%d ",ans); } return 0; }