[HNOI 2004]宠物收养所

来源:互联网 发布:kindle使用 知乎 编辑:程序博客网 时间:2024/04/29 16:40

同样是HNOI的一道水题,非常鄙视那些用set的人……

其实这是一道平衡树维护的题,很显而易见要维护两颗平衡树(好吧最开始做题目居然只建立了一棵SplayTree,然后WA到想哭……),而且两棵树中必然有一颗是空的,易证。

无非就是注意几个特别的操作,详见代码。

#include <cstdio>#define abs(x) (((x)>=0)? (x):-(x))#define MaxN 80010using namespace std;int ans,n;struct splaytree{int a[MaxN],l[MaxN],r[MaxN];int t,tot;inline void zig(int &x){int lc=l[x];l[x]=r[lc];r[lc]=x;x=lc;}inline void zag(int &x){int rc=r[x];r[x]=l[rc];l[rc]=x;x=rc;}inline void splay(int &t,int x){if(!t) return;int pl=0,pr=0;for(;;){if(x==a[t]) break;if(x<a[t]&&!l[t]) break;if(x>a[t]&&!r[t]) break;if(x<a[t]){if(x<a[l[t]]&&l[l[t]])zig(t);l[pr]=t,pr=t,t=l[t]; }else{if(x>a[r[t]]&&r[r[t]])zag(t);r[pl]=t,pl=t,t=r[t];}}l[pr]=r[t];r[pl]=l[t];l[t]=r[0];r[t]=l[0];l[0]=r[0]=0;}inline void insert(const int &x){a[++tot]=x;if(!t){t=tot;return;}splay(t,x);if(x<a[t])l[tot]=l[t],l[t]=tot;elser[tot]=r[t],r[t]=tot;}inline void suit(const int &x){if(!t) return;splay(t,x);splay(l[t],a[t]);splay(r[t],a[t]);int pl=abs(a[l[t]]-x),pm=abs(a[t]-x),pr=abs(a[r[t]]-x);if(x<a[t]&&pl<=pm&&l[t]){ans+=pl;ans%=1000000;l[t]=l[l[t]];}else if(x>a[t]&&pr<pm&&r[t]){ans+=pr;ans%=1000000;r[t]=r[r[t]];}else{ans+=pm;ans%=1000000;if(l[t])r[l[t]]=r[t],t=l[t];else if(r[t])l[r[t]]=l[t],t=r[t];else t=0;}}}SP[2];int main(){freopen("in","r",stdin);freopen("out","w",stdout);int x,y;scanf("%d",&n);while(n--){scanf("%d%d",&x,&y);if(SP[x].t)SP[x].suit(y);elseSP[!x].insert(y);}printf("%d",ans);return 0;} 

0 0