AC日记——宠物收养所 bzoj 1208
思路:
一棵splay树;
如果来者是宠物且树空,就将其加入树中;
如果树不空,则查找前驱后继,取最优,然后删点;
对人亦然;
注意边界和取模,最后的ans用long long其余用int即可;
来,上代码:
#include <cstdio> #include <iostream> #include <algorithm> using namespace std; #define maxn 80005 #define mod 1000000 #define INF 0x7fffffff struct TreeNodeType { int w,key,opi,size,ch[2]; void destroy() { w=key=opi=size=ch[0]=ch[1]=0; } void create(int x) { destroy(); key=x; } }; struct TreeNodeType tree[maxn<<1]; int n,tot,flag,root; long long ans; inline int getson(int now) { return tree[tree[now].opi].ch[1]==now; } inline void updata(int now) { tree[now].size=tree[now].w; if(tree[now].ch[0]) tree[now].size+=tree[tree[now].ch[0]].size; if(tree[now].ch[1]) tree[now].size+=tree[tree[now].ch[1]].size; } inline void rotate(int now) { int opi=tree[now].opi,fopi=tree[opi].opi,pos=getson(now); tree[opi].ch[pos]=tree[now].ch[pos^1]; tree[tree[opi].ch[pos]].opi=opi,tree[now].opi=fopi; if(fopi) tree[fopi].ch[getson(opi)]=now; tree[opi].opi=now,tree[now].ch[pos^1]=opi; updata(opi),updata(now); } void splay(int now) { for(int opi;opi=tree[now].opi;rotate(now)) { if(tree[opi].opi) rotate(getson(now)==getson(opi)?opi:now); } root=now; } void insert(int x) { if(!root) tree[++tot].create(x),root=tot; else { int now=root,opi=0; while(1) { if(tree[now].key==x) { tree[now].w++; tree[now].size++; splay(now); return ; } opi=now,now=tree[now].ch[x>tree[now].key]; if(!now) { tree[++tot].create(x); tree[tot].opi=opi; tree[opi].ch[x>tree[opi].key]=tot; splay(tot); return ; } } } } inline int pre() { if(tree[root].w>1) return root; if(!tree[root].ch[0]) return 0; int now=tree[root].ch[0]; while(tree[now].ch[1]) now=tree[now].ch[1]; return now; } inline int suc() { if(tree[root].w>1) return root; if(!tree[root].ch[1]) return 0; int now=tree[root].ch[1]; while(tree[now].ch[0]) now=tree[now].ch[0]; return now; } void del() { if(tree[root].w>1) { tree[root].w--; tree[root].size--; return ; } if(!tree[root].ch[0]&&!tree[root].ch[1]) { tree[root].destroy(); root=0;tree[root].destroy();return ; } if(tree[root].ch[0]&&!tree[root].ch[1]) { int tmp=root; root=tree[root].ch[0]; tree[tmp].destroy(); tree[root].opi=0; return ; } if(!tree[root].ch[0]&&tree[root].ch[1]) { int tmp=root; root=tree[root].ch[1]; tree[tmp].destroy(); tree[root].opi=0; return ; } int tmp=pre(),pos=root; tree[tmp].ch[1]=tree[root].ch[1]; tree[tree[tmp].ch[1]].opi=tmp; root=tree[root].ch[0],tree[root].opi=0; tree[pos].destroy(); splay(tree[tmp].ch[1]); } int main() { scanf("%d",&n);int ty,x; while(n--) { scanf("%d%d",&ty,&x); if(!root) { flag=ty; insert(x); } else { if(ty==flag) insert(x); else { insert(x); int pr=pre(),su=suc(),to; if(!pr) ans+=abs(tree[su].key-x),to=su; else if(!su) ans+=abs(tree[pr].key-x),to=pr; else { if(abs(tree[pr].key-x)<=abs(tree[su].key-x)) ans+=abs(tree[pr].key-x),to=pr; else ans+=abs(tree[su].key-x),to=su; } del(),splay(to),del(); } } } cout<<ans%mod; return 0; }