您的位置:首页 > 其它

【bzoj1208】[HNOI2004]宠物收养所

2017-03-02 21:23 274 查看
啊啊啊啊,好久不写splay这个题调了一晚上,其实就是一道平衡树的裸题,考虑其实查询的时候是不分宠物和主人的,维护一颗平衡树就好,话说这道题好像可以被set+lower_bound水过去,STL大法吼啊.

其实我写出来之后基本写对了,但是还是调了一晚上= =,答案忘记取模了,这好像已经不是我第一次犯这种错误了,平时读题一定要仔细.

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>

using namespace std;
const int N=100010,inf=0x3f3f3f3f;
int n,mx;
inline int F()
{
register int aa,bb;register char ch;
while(ch=getchar(),(ch<'0'||ch>'9')&&ch!='-');ch=='-'?aa=bb=0:(aa=ch-'0',bb=1);
while(ch=getchar(),ch<='9'&&ch>='0')aa=(aa<<3)+(aa<<1)+ch-'0';return bb?aa:-aa;
}
struct SplayTree{
int root,sz;
int ch
[2],f
,size
,cnt
,key
;
inline void clear(int x){size[x]=cnt[x]=ch[x][0]=ch[x][1]=f[x]=key[x]=0;}
inline int get(int x){return ch[f[x]][1]==x;}
inline void updata(int x)
{
if (!x)return;
size[x]=cnt[x];
if (ch[x][0])size[x]+=size[ch[x][0]];
if (ch[x][1])size[x]+=size[ch[x][1]];
}
inline void rotate(int x)
{
int old=f[x],oldf=f[old],which=get(x);
ch[old][which]=ch[x][which^1];f[ch[x][which^1]]=old;
ch[x][which^1]=old;f[old]=x;f[x]=oldf;
if (oldf)
{
ch[oldf][ch[oldf][1]==old]=x;
}
updata(x),updata(old);
}
inline void splay(int x)
{
for (int fa;(fa=f[x]);rotate(x))
if (f[fa])rotate(get(x)==get(fa)?fa:x);
root=x;
}
inline void insert(int x)
{
if (!root){key[++sz]=x;size[sz]=cnt[sz]=1;f[sz]=ch[sz][0]=ch[sz][1]=0;root=sz;return;}
int now=root,fa;
while(1)
{
if (key[now]==x){cnt[now]++;updata(sz),updata(fa),splay(now);return;}
fa=now;
now=ch[now][key[now]<x];
if (now==0)
{
f[++sz]=fa;
key[sz]=x;
ch[fa][key[fa]<x]=sz;
ch[sz][0]=ch[sz][1]=0;
cnt[sz]=size[sz]=1;
updata(fa);splay(sz);return;
}
}
}
inline int findpos(int x)
{
int ans=0,now=root;
while (1)
{
if (x<key[now])now=ch[now][0];
else
{
ans+=(ch[now][0]?size[ch[now][0]]:0);
if (x==key[now]){splay(now);return ans+1;}
ans+=cnt[now];now=ch[now][1];
}
}
}
inline int pre()
{
int now=ch[root][0];
while(ch[now][1])now=ch[now][1];
return now;
}
inline int suc()
{
int now=ch[root][1];
while(ch[now][0])now=ch[now][0];
return now;
}
inline void del(int x)
{
int whatever=findpos(x);
//      cout<<"root "<<root<<' '<<cnt[root]<<" x "<<x<<endl;
if (cnt[root]>1){cnt[root]--;updata(root);return;}
if (!ch[root][0]&&!ch[root][1]){clear(root);root=0;return;}
if (!ch[root][0]){int oldroot=root;root=ch[oldroot][1];clear(oldroot);f[root]=0;return;}
if (!ch[root][1]){int oldroot=root;root=ch[oldroot][0];clear(oldroot);f[root]=0;return;}
int leftbig=pre(),oldroot=root;
splay(leftbig);
f[ch[oldroot][1]]=root;
ch[root][1]=ch[oldroot][1];
clear(oldroot);
updata(root);
return;
}
inline void solve(int x)
{
int cp=inf,cs
becc
=inf;
int ans=0,s,p;
insert(x);
p=ch[root][0]?pre():0;
s=ch[root][1]?suc():0;
if (p)cp=x-key[p];
if (s)cs=key[s]-x;
if (cp<=cs)mx=(mx+cp)%1000000,del(key[p]);
else mx=(mx+cs)%1000000,del(key[s]);
del(x);
}
}T;
int main()
{
n=F();mx=0;
int x,y,z[2]={0};
for(int i=1;i<=n;++i)
{
x=F(),y=F();
z[x]++;
if (z[x]>z[x^1])T.insert(y);
else T.solve(y);
}
cout<<mx%1000000;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: