bzoj1208
splay 120ms
#include<cstdio> #include<cctype> #include<algorithm> #define maxn 80002 #define mod 1000000 using namespace std; int n,rt,typ,sz,ans,t1,t2; int cnt[maxn],siz[maxn],f[maxn],tr[maxn][2],key[maxn]; inline void read(int &x){ char ch=getchar();x=0;int f=1; while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} x*=f; } inline void clear(int x){ tr[x][0]=tr[x][1]=f[x]=siz[x]=cnt[x]=key[x]=0; } void updata(int x){ if(x){ siz[x]=cnt[x]; if(tr[x][0])siz[x]+=siz[tr[x][0]]; if(tr[x][1])siz[x]+=siz[tr[x][1]]; } } void rotate(int x){ int old=f[x],oldf=f[old],whicx=(tr[f[x]][1]==x); tr[old][whicx]=tr[x][whicx^1];f[tr[old][whicx]]=old; tr[x][whicx^1]=old;f[old]=x; f[x]=oldf; if(oldf)tr[oldf][tr[oldf][1]==old]=x; updata(old);updata(x); } void splay(int x){ for(int fa;fa=f[x];rotate(x)) if(f[fa])rotate((tr[f[x]][1]==x)==(tr[f[fa]][1]==fa)?fa:x); rt=x; } void insert(int x){ if(!rt){sz++;tr[sz][0]=tr[sz][1]=f[sz]=0;rt=sz;siz[sz]=cnt[sz]=1;key[sz]=x;return;}// int now=rt,fa=0; while(1){ if(x==key[now]){cnt[now]++;updata(now);updata(fa);splay(now);break;} fa=now; now=tr[now][key[now]<x]; if(now==0){ sz++; tr[sz][0]=tr[sz][1]=0; f[sz]=fa; siz[sz]=cnt[sz]=1; tr[fa][key[fa]<x]=sz; key[sz]=x; updata(fa); splay(sz); break; } } } (一开始没看题目,考虑了特点值和希望值一样的情况) inline int pre(){ int now=tr[rt][0]; while(tr[now][1])now=tr[now][1]; return now; } inline int nex(){ int now=tr[rt][1]; while(tr[now][0])now=tr[now][0]; return now; } inline void pre(int b){ for(int x=rt;x;){ if(key[x]<=b){t1=x;x=tr[x][1];}else x=tr[x][0]; } } inline void nex(int b){ for(int x=rt;x;){ if(key[x]>=b){t2=x;x=tr[x][0];}else x=tr[x][1]; } } void del(int x){ splay(x); if(cnt[rt]>1){cnt[rt]--;updata(rt);return;} if(!tr[rt][0]&&!tr[rt][1]){clear(rt);rt=0;return;} if(!tr[rt][0]){int oldrt=rt;rt=tr[rt][1];f[rt]=0;clear(oldrt);return;} if(!tr[rt][1]){int oldrt=rt;rt=tr[rt][0];f[rt]=0;clear(oldrt);return;} int lefb=pre(),oldrt=rt; splay(lefb); tr[rt][1]=tr[oldrt][1]; f[tr[oldrt][1]]=rt; clear(oldrt); updata(rt); } int main(){ read(n); int a,b; while(n--){ read(a);read(b); if(!rt){typ=a;insert(b);}else if(a==typ)insert(b); else{ t1=t2=-1; pre(b);nex(b); if(t1==-1){ans+=key[t2]-b;ans%=mod;del(t2);}else if(t2==-1){ans+=b-key[t1];ans%=mod;del(t1);}else{ if(b-key[t1]>key[t2]-b){ans+=key[t2]-b;ans%=mod;del(t2);} else{ans+=b-key[t1];ans%=mod;del(t1);} } } } printf("%d\n",ans); }
sbt(抄板子的)216ms
#include<cstdio> #include<cstring> #include<cctype> #define mod 1000000 #define maxn 80001 using namespace std; int rt,sz,man,n; struct data{int l,r,siz,key;void init(int val){l=r=0;siz=1;key=val;}}sbt[maxn]; inline void read(int &x){ char ch=getchar();x=0;int f=1; while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} x*=f; } void zig(int &t){ int k=sbt[t].r; sbt[t].r=sbt[k].l; sbt[k].l=t; sbt[k].siz=sbt[t].siz; sbt[t].siz=sbt[sbt[t].l].siz+sbt[sbt[t].r].siz+1; t=k; } void zag(int &t){ int k=sbt[t].l; sbt[t].l=sbt[k].r; sbt[k].r=t; sbt[k].siz=sbt[t].siz; sbt[t].siz=sbt[sbt[t].l].siz+sbt[sbt[t].r].siz+1; t=k; } void maintain(int &x,bool flag){ if(!flag){ if(sbt[sbt[sbt[x].l].l].siz>sbt[sbt[x].r].siz)zag(x); else if(sbt[sbt[sbt[x].l].r].siz>sbt[sbt[x].r].siz){ zig(sbt[x].l);zag(x); }else return; } else{ if(sbt[sbt[sbt[x].r].r].siz>sbt[sbt[x].l].siz)zig(x); else if(sbt[sbt[sbt[x].r].l].siz>sbt[sbt[x].l].siz){ zag(sbt[x].r);zig(x); }else return; } maintain(sbt[x].l,0); maintain(sbt[x].r,1); maintain(x,0); maintain(x,1); } void insert(int &x,int key){ if(!x){x=++sz;sbt[x].init(key);} else{ sbt[x].siz++; insert(key<sbt[x].key?sbt[x].l:sbt[x].r,key); maintain(x,key>=sbt[x].key); } } int del(int &x,int key){ if(!x)return 0; sbt[x].siz--; if(key==sbt[x].key||(key<sbt[x].key&&!sbt[x].l)||(key>sbt[x].key&&!sbt[x].r)){ if(sbt[x].l&&sbt[x].r){ int pos=del(sbt[x].l,key+1); sbt[x].key=sbt[pos].key; return pos; }else{ int pos=x; x=sbt[x].l+sbt[x].r; return pos; } } else return del(key<sbt[x].key?sbt[x].l:sbt[x].r,key); } int pre(int x,int key){ if(!x)return key; if(key<=sbt[x].key)return pre(sbt[x].l,key); else{ int tmp=pre(sbt[x].r,key); return key==tmp?sbt[x].key:tmp; } } int nex(int x,int key){ if(!x)return key; if(key>=sbt[x].key)return nex(sbt[x].r,key); else{ int tmp=nex(sbt[x].l,key); return key==tmp?sbt[x].key:tmp; } } int main(){ while(scanf("%d",&n)!=EOF){ int a,b,typ,ans=0;rt=sz=0; while(n--){ read(a);read(b); if(!rt){ man=a;insert(rt,b); } else{ if(man==a)insert(rt,b); else { int x=pre(rt,b);int y=nex(rt,b); int tmp1=b-x,tmp2=y-b; if(tmp1==0){ans=(ans+tmp2)%mod;del(rt,y);} else if(tmp2==0){ans=(ans+tmp1)%mod;del(rt,x);} else if(tmp1<=tmp2){ans=(ans+tmp1)%mod;del(rt,x);} else {ans=(ans+tmp2)%mod;del(rt,y);} } } } printf("%d\n",ans); } }