题解:
发现每一个动物和每一个收养动物的是一样的,所以只需要一颗平衡树
维护pre,nxt
每一次计算去走pre或者nxt
然后删除
代码:
#include<bits/stdc++.h> using namespace std; const int N=800005,M=1000000; long long ans; int data[N],x,p,n,y,root,tot,pre[N],c[N][2],size[N]; void rot(int x) { int y=pre[x],k=(c[y][0]==x); size[y]=size[c[y][k]]+size[c[x][k]]+1; size[x]=size[c[x][!k]]+size[y]+1; c[y][!k]=c[x][k]; pre[c[y][!k]]=y; pre[x]=pre[y]; if(pre[y])c[pre[y]][c[pre[y]][1]==y]=x; c[x][k]=y;pre[y]=x; } void splay(int x,int g) { for(int y=pre[x];y!=g;rot(x),y=pre[x]) if(pre[y]!=g)rot((x==c[y][0])==(y==c[pre[y]][0])?y:x); if(g==0)root=x; } void insert(int x) { int y=root; while(c[y][x>data[y]]) y=c[y][x>data[y]]; data[++tot]=x; c[tot][0]=c[tot][1]=0; pre[tot]=y; if(y)c[y][x>data[y]]=tot; splay(tot,0); } void del(int x) { int y=root; while(data[y]!=x) y=c[y][x>data[y]]; splay(y,0); y=c[root][1]; bool b; if(!y) b=1,y=c[root][0];else b=0; while(c[y][b]) y=c[y][b]; splay(y,root); c[y][b]=c[root][b];pre[c[root][b]]=y;pre[y]=0;root=y; size[y]=size[c[y][!b]]+size[c[y][b]]; } int findpre(int x) { int ans=-1; for(int y=root;y;) if(data[y]<x)ans=y,y=c[y][1]; else y=c[y][0]; return ans; } int findnxt(int x) { int ans=-1; for(int y=root;y;) if(data[y]<=x)y=c[y][1]; else ans=y,y=c[y][0]; return ans; } int main() { scanf("%d",&n);n--; scanf("%d%d",&p,&x); insert(x);int qq=1; while (n--) { scanf("%d%d",&y,&x); if (y==p)qq++;else qq--; if (p==y)insert(x); else { if (qq==-1) { p^=1;qq=1; insert(x); continue; } int p1=findpre(x),p2=findnxt(x); if (p1!=-1&&(p2==-1||x-data[p1]<=data[p2]-x)) { ans+=(x-data[p1]); del(data[p1]); } else { ans+=(data[p2]-x); del(data[p2]); } } } printf("%lld",ans%M); }