第三道splay的裸题了,然而我还是调了一上午……
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1208
#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int n,fa[80005],num[80005],tr[80005][2],t,x,rt,size,root,ans,t1,t2;
void rorate(int x,int &k)
{
int y=fa[x],z=fa[y],l,r;
if (tr[y][0]==x) l=0;else l=1;
r=l^1;
if (y==k) k=x;
else{if(tr[z][0]==y)tr[z][0]=x;else tr[z][1]=x;}
fa[x]=z;fa[y]=x;fa[tr[x][r]]=y;
tr[y][l]=tr[x][r];tr[x][r]=y;
}
void splay(int x,int &k)
{
int y,z;
while (x!=k)
{
y=fa[x];
z=fa[y];
if (y!=k)
{
if ((tr[y][0]==x)^(tr[z][0]==y)) rorate(x,k);
else rorate(y,k);
}
rorate(x,k);
}
}
void del(int x)
{
splay(x,rt);
if (tr[x][0]*tr[x][1]==0)
{
rt=tr[x][0]+tr[x][1];
}
else
{
int k=tr[x][1];
while (tr[k][0]) k=tr[k][0];
tr[k][0]=tr[x][0];
fa[tr[x][0]]=k;
rt=tr[x][1];
}
fa[rt]=0;
}
void inser(int &k,int x,int last)
{
if (k==0) {size++;k=size;num[k]=x;fa[k]=last;splay(k,rt);return;}
else if (x<num[k]) inser(tr[k][0],x,k); else inser(tr[k][1],x,k);
}
void qian(int k,int x)
{
if (k==0) return;
if (num[k]<=x) {t1=k;qian(tr[k][1],x);}
else qian(tr[k][0],x);
}
void hou(int k,int x)
{
if (k==0) return;
if (num[k]>=x)
{
t2=k;
hou(tr[k][0],x);
}
else hou(tr[k][1],x);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&t,&x);
if (!rt) {root=t;inser(rt,x,0);}
else if(root==t) {inser(rt,x,0);}
else
{
t1=-1;
t2=-1;
qian(rt,x); hou(rt,x);
if (t1==-1) {ans=(ans+num[t2]-x)%1000000;del(t2);}
else if(t2==-1) {ans=(ans+x-num[t1])%1000000;del(t1);}
else
{
if (num[t2]-x<x-num[t1]){ans=(ans+num[t2]-x)%1000000;del(t2);}
else {ans=(ans+x-num[t1])%1000000;del(t1);}
}
}
}
printf("%d",ans);
}
这里还有一种set的写法(by hzwer)(虽然前一种我也看了一下黄学长的思路),毕竟stl大法好,(然而我不会).
#include<map>
#include<set>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define mod 1000000
#define pi acos(-1)
#define inf 0x7fffffff
#define ll long long
using namespace std;
ll read()
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int t,n,ans;
set<int>st;
void query(int x)
{
set<int>::iterator l=--st.lower_bound(x),r=st.lower_bound(x);
if(x-*l<=*r-x&&*l!=-inf)
{
ans+=x-*l;
st.erase(l);
}
else
{
ans+=*r-x;
st.erase(r);
}
ans%=mod;
}
int main()
{
st.insert(inf);
st.insert(-inf);
n=read();
for(int i=1;i<=n;i++)
{
int a=read(),b=read();
if(st.size()==2)
{
t=a;
st.insert(b);
}
else if(a==t)st.insert(b);
else query(b);
}
printf("%d",ans);
return 0;
}