HNOI2004 宠物收养所

来源:互联网 发布:淘宝卖家论坛社区 编辑:程序博客网 时间:2024/04/28 14:38

大致题意:如果一个人来的时候有狗就挑狗,没有就留下来等;狗也是,有很多人来等着领养就挑人,没有就留下来。最后使喜爱值(?)之和最小。挑选的方式是取喜爱值(=|a-b|)最大的(相同则选小的那个)

【超级简化版= =如果不是已经理解了题意可能我自己都看不懂Orz】


题解:这个跟 营业额统计 那题差不多,多了个标记。标记一下当前这个树里的是人还是狗。判断一下当前操作的与树里的是不是同种生物,然后相应做出处理就好了。

#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define maxn 101000#define mod 1000000int root;struct node{int d,c,f,son[2];}tr[maxn*2];int len,bk;void updata(int now){int lc=tr[now].son[0],rc=tr[now].son[1];tr[now].c=tr[lc].c+tr[rc].c+1;}void add(int d,int f){len++;tr[len].son[0]=tr[len].son[1]=0;tr[len].c=1;tr[len].d=d;tr[len].f=f;if (d<tr[f].d) tr[f].son[0]=len;else tr[f].son[1]=len;}void rotate(int x){int y=tr[x].f,z=tr[y].f,w,r,R;if (x==tr[y].son[0]) w=1;else w=0;r=tr[x].son[w];R=y;tr[R].son[1-w]=r;if (r!=0) tr[r].f=R;r=x;R=z;tr[R].son[ (tr[R].son[0]==y)?0:1]=r;tr[r].f=R;r=y;R=x;tr[R].son[w]=r;tr[r].f=R;updata(y);updata(x);}void splay(int x,int rt){while (tr[x].f!=rt){int y=tr[x].f,z=tr[y].f;if (z==rt) rotate(x);else{if ((y==tr[z].son[0])==(x==tr[y].son[0])) rotate(y);else rotate(x);rotate(x);}}if (rt==0) root=x;}int findip(int d){int x=root;while (tr[x].d!=d){if (d<tr[x].d){if (tr[x].son[0]!=0) x=tr[x].son[0];else break;}else{if (tr[x].son[1]!=0) x=tr[x].son[1];else break;}}return x;}void ins(int d){if (root==0) {add(d,0);root=len;return;}int x=findip(d);add(d,x);updata(x);splay(x,0);}void del(int d){int x=findip(d);splay(x,0);if (tr[x].son[0]==0 && tr[x].son[1]==0) root=len=0;else if (tr[x].son[0]==0 && tr[x].son[1]!=0) {root=tr[x].son[1];tr[root].f=0;}else if (tr[x].son[1]==0 && tr[x].son[0]!=0) {root=tr[x].son[0];tr[root].f=0;}else{int p=tr[x].son[0];while (tr[p].son[1]!=0) p=tr[p].son[1];splay(p,x);root=p;tr[p].f=0;tr[p].son[1]=tr[x].son[1];tr[tr[x].son[1]].f=p;updata(p);}}int findqianji(int d){int x=findip(d);splay(x,0);if (d==tr[x].d) return d;if (d<tr[x].d && tr[x].son[0]!=0){x=tr[x].son[0];while (tr[x].son[1]!=0) x=tr[x].son[1];}if (d<tr[x].d) x=0;return tr[x].d;}int findhouji(int d){int x=findip(d);splay(x,0);if (d==tr[x].d) return d;if (d>tr[x].d && tr[x].son[1]!=0){x=tr[x].son[1];while (tr[x].son[0]!=0) x=tr[x].son[0];}if (d>tr[x].d) x=0;return tr[x].d;}int main(){//freopen("pet.in","r",stdin);//freopen("pet.out","w",stdout);int n,i,c,x,ans=0;scanf("%d",&n);bk=0;//bk是标记root=len=0;for (i=1;i<=n;i++){scanf("%d%d",&c,&x);if (root==0) bk=c;if (c==bk) ins(x);//同种!那就插进树里else//不同种就在树中找最接近的~(前驱or后继){int p=findqianji(x);int q=findhouji(x);if (p==0 && q!=0) {ans+=abs(x-q);del(q);}        else if (p!=0 && q==0) {ans+=abs(x-p);del(p);}else if (p!=0 && q!=0){if (abs(x-p)>abs(x-q)) {ans+=abs(x-q);del(q);}else {ans+=abs(x-p);del(p);} }ans%=mod;}}printf("%d\n",ans);return 0;}


0 0
原创粉丝点击