題目來源:http://www.lydsy.com/JudgeOnline/problem.php?id=1208
這是一份極其“優美”的代碼,本來以爲附帶大常數,結果和hzwer的跑的一樣快。。。雖然代碼本身確實比較差
splay建一棵即可,在樹上標上當前是“寵物樹”還是“領養者樹”。
findval用來找小於等於x的最大值y的位置。比較abs(y-b)和abs(y的後繼-b)的大小,注意判斷x小於樹中的所有值的情況,此時findval會返回0。
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lch ch[x][0]
#define rch ch[x][1]
using namespace std;
const int N=100010,mod=1000000;
int n,ans=0;
bool flag;
int read () {
int 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;
}
struct Splay {
int ch[N][2],f[N],cnt,root,opt;
int a[N],s[N];
void pushup (int x) {
s[x]=s[ch[x][0]]+s[ch[x][1]]+1;
}
int grow (int k,int fa) {
int x=++cnt;
a[x]=k,s[x]=1;
ch[x][0]=ch[x][1]=0,f[x]=fa;
return x;
}
void rotate (int x) {
int y=f[x],opt;
if (ch[y][0]==x) opt=0;else opt=1;
ch[y][opt]=ch[x][!opt];
if (ch[x][!opt]) f[ch[x][!opt]]=y;
f[x]=f[y];
if (root==y) root=x;
else if (ch[f[y]][0]==y) ch[f[y]][0]=x;
else ch[f[y]][1]=x;
ch[x][!opt]=y,f[y]=x;
pushup(y),pushup(x);
}
void splay (int x,int to=0) {
while (f[x]!=to) {
if (f[f[x]]==to) rotate(x);
else if ((ch[f[f[x]]][0]==f[x])
==(ch[f[x]][0]==x))
rotate(f[x]),rotate(x);
else rotate(x),rotate(x);
}
}
int findval (int k) {
int x=root,ans=0;flag=0;
while (x) {
if (k==a[x]) { flag=1;return x; }
else if (k<a[x]) x=ch[x][0];
else ans=x,x=ch[x][1];
}
return ans;
}
int findkth (int k) {
int x=root;
while (x) {
if (k==s[ch[x][0]]+1)
return x;
else if (k<s[ch[x][0]]+1) x=ch[x][0];
else k-=s[ch[x][0]]+1,x=ch[x][1];
}
}
void insert (int k) {
if (root==0) root=grow(k,0);
else {
int x=root;
while (x) {
if (k==a[x]) { break; }
else {
int &y=(k<a[x]?ch[x][0]:ch[x][1]);
if (!y) { x=y=grow(k,x);break; }
else x=y;
}
}
splay(x);
}
}
void erase (int x) {
splay(x);
int p=ch[x][0];
while (ch[p][1]) p=ch[p][1];
if (p) {
splay(p,root);
ch[p][1]=ch[root][1];
f[f[ch[root][1]]=p]=0;//這裏之前敲錯了
pushup(root=p);
}
else {
if (ch[root][1]) f[ch[root][1]]=0,root=ch[root][1];
else root=cnt=0;
}
}
int next (int x) {
splay(x);
int p=ch[x][1];
while (ch[p][0]) p=ch[p][0];
if (p) return p;
return 0;
}
Splay () { cnt=root=0; }
}Sp;
int main () {
int c,x,t,u,v,tmp;
n=read();
for (int i=1;i<=n;i++) {
c=read();x=read();
if (!Sp.cnt) { Sp.opt=c;Sp.insert(x); }
else if (c==Sp.opt) Sp.insert(x);
else {
t=Sp.findval(x);
if (t) {
u=abs(Sp.a[t]-x);
if (flag) Sp.erase(t);
if (!flag) {
if (tmp=Sp.next(t)) {
v=abs(Sp.a[tmp]-x);
if (u<=v) { ans=(ans+u)%mod;Sp.erase(t); }
else if (u>v) { ans=(ans+v)%mod;Sp.erase(tmp); }
}
else { ans=(ans+u)%mod;Sp.erase(t); }
}
}
else { tmp=Sp.findkth(1);ans=(ans+abs(Sp.a[tmp]-x))%mod;Sp.erase(tmp); }
}
}
printf("%d\n",ans);
}