analysis
显然嘛,建两颗平衡树,一颗对人来操作,一颗对动物来操作
其实建两颗平衡树真的不像我原来想象的那么麻烦(要复制粘贴一次??),其实只需要写一个类(class)封装一下就好了(结构体也可以,只是low了一点),只需要打一棵树的板子,然后命名两个类变量就好了,不然的话,建n颗树不是要复制粘贴n次??
这次打Splay打的比较顺利,交上去一遍过,可能是因为在提交前对拍了一下吧
不拍不知道,一排还吓一跳,我的inf又双叒出锅了。。
inf这次开了LONG_LONG_MAX-10,然后这个值和1291一加,再取个绝对值,就炸了。。
开INT_MAX吧,不大不小刚刚好
code
#include<bits/stdc++.h>
using namespace std;
#define loop(i,start,end) for(int i=start;i<=end;++i)
#define anti_loop(i,start,end) for(int i=start;i>=end;--i)
#define clean(arry,num) memset(arry,num,sizeof(arry))
#define ll long long
const int mod=1000000;
template<typename T>void read(T &x){
x=0;char r=getchar();T neg=1;
while(r>'9'||r<'0'){if(r=='-')neg=-1;r=getchar();}
while(r>='0'&&r<='9'){x=(x<<1)+(x<<3)+r-'0';r=getchar();}
x*=neg;
}
const int maxn=80000+10;
class BBT{
public:
struct node{int f;int son[2];int siz;int cnt;ll w;}tree[maxn];
int root,nfp;
bool getpos(int pos){return tree[tree[pos].f].son[1]==pos;}
void update(int pos){tree[pos].siz=tree[tree[pos].son[0]].siz+tree[tree[pos].son[1]].siz+tree[pos].cnt;}
void Rotate(int x){
int f=tree[x].f;
int ff=tree[f].f;
int posx=getpos(x),posf=getpos(f);
int s=tree[x].son[posx^1];
tree[x].f=ff;
tree[ff].son[posf]=x;
tree[x].son[posx^1]=f;
tree[f].f=x;
tree[f].son[posx]=s;
tree[s].f=f;
update(f);update(x);
}
void Splay(int pos,int to=0){
int f,ff;
while(tree[pos].f!=to){
f=tree[pos].f;ff=tree[f].f;
if(ff!=to)Rotate((getpos(pos)==getpos(f))?f:pos);
Rotate(pos);
}if(to==0)root=pos;
}
void Insert(ll w){
int cur=root;int p=0;
while(cur&&tree[cur].w!=w){p=cur;cur=tree[cur].son[w>tree[cur].w];}
if(cur)++tree[cur].cnt;
else{
cur=++nfp;
tree[cur].cnt=tree[cur].siz=1;
tree[cur].f=p;tree[cur].son[0]=tree[cur].son[1]=0;
tree[cur].w=w;
if(p)tree[p].son[tree[p].w<w]=cur;
}Splay(cur);
}
void Find(ll w){
int cur=root;
while(tree[cur].w!=w&&tree[cur].son[tree[cur].w<w])cur=tree[cur].son[tree[cur].w<w];
Splay(cur);
}
int Pre(ll w){
Find(w);
if(tree[root].w<w)return root;
int cur=tree[root].son[0];
while(tree[cur].son[1])cur=tree[cur].son[1];
Splay(cur);return cur;
}
int Bac(ll w){
Find(w);
if(tree[root].w>w)return root;
int cur=tree[root].son[1];
while(tree[cur].son[0])cur=tree[cur].son[0];
Splay(cur);return cur;
}
void Delete(int w){
int pre=Pre(w);
int bac=Bac(w);
Splay(pre),Splay(bac,pre);
if(tree[tree[bac].son[0]].cnt>1)--tree[tree[bac].son[0]].cnt;
else tree[bac].son[0]=0;
}
void initialize(){root=0;nfp=0;}
}Pet,Man;
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>类
int n;
const ll inf=INT_MAX-100;
int main(){
freopen("in.txt","r",stdin);
Pet.initialize();Man.initialize();
Pet.Insert(inf);
Pet.Insert(-inf);
Man.Insert(inf);
Man.Insert(-inf);
read(n);
int ai;
ll bi;
int res=0;
int nfP=0,nfM=0;
loop(i,1,n){
read(ai),read(bi);
if(nfP==0&&nfM==0){
if(ai==0)Pet.Insert(bi),++nfP;
else if(ai==1)Man.Insert(bi),++nfM;
}
else{
if(ai==0){
if(nfP&&nfM==0){
Pet.Insert(bi);
++nfP;
}
else if(nfP==0&&nfM){
int pre=Man.Pre(bi);
int bac=Man.Bac(bi);
if(abs(Man.tree[pre].w-bi)<=abs(Man.tree[bac].w-bi))
Man.Delete(Man.tree[pre].w),res=(res+abs(Man.tree[pre].w-bi))%mod;
else if(abs(Man.tree[pre].w-bi)>abs(Man.tree[bac].w-bi))
Man.Delete(Man.tree[bac].w),res=(res+abs(Man.tree[bac].w-bi))%mod;
--nfM;
}
}
else if(ai==1){
if(nfP&&nfM==0){
int pre=Pet.Pre(bi);
int bac=Pet.Bac(bi);
if(abs(Pet.tree[pre].w-bi)<=abs(Pet.tree[bac].w-bi))
Pet.Delete(Pet.tree[pre].w),res=(res+abs(Pet.tree[pre].w-bi))%mod;//inf再次背锅
else if(abs(Pet.tree[pre].w-bi)>abs(Pet.tree[bac].w-bi))
Pet.Delete(Pet.tree[bac].w),res=(res+abs(Pet.tree[bac].w-bi))%mod;
--nfP;
}
else if(nfP==0&&nfM){
Man.Insert(bi);
++nfM;
}
}
}
}
printf("%d\n",res);
return 0;
}