谦谦君子 @ 2020-02-27 22:17:20
#include<bits/stdc++.h>
using namespace std;
const int maxn=1000005;
int n,m,root,cnt,ans,last;
int father[maxn],val[maxn],son[maxn][2],sum[maxn],size[maxn];
int read()
{
int s=0,f=1;
char ch=getchar();
while (!isdigit(ch))
{
if (ch==45)
{
f=-1;
}
ch=getchar();
}
while (ch>='0'&&ch<='9')
{
s=s*10+ch-'0';
ch=getchar();
}
return s*f;
}
void clear(int x)
{
father[x]=son[x][0]=son[x][1]=val[x]=size[x]=sum[x]=0;
return ;
}
int get(int x)
{
return son[father[x]][1]==x;
}
void update(int x)
{
if (x!=0)
{
size[x]=sum[x];
if (son[x][0])
{
size[x]+=size[son[x][0]];
}
if (son[x][1])
{
size[x]+=size[son[x][1]];
}
}
return ;
}
void connect(int x,int y,int z)
{
if (x)
{
father[x]=y;
}
if (y)
{
son[y][z]=x;
}
return ;
}
void rotate(int x)
{
int fa=father[x],ffa=father[fa],m=get(x),n=get(fa);
connect(son[x][m^1],fa,m);
connect(fa,x,m^1);
connect(x,ffa,n);
update(fa);
update(x);
}
void splay(int x)
{
for (int fa;fa=father[x];rotate(x))
{
if (father[fa])
{
if (get(x)==get(fa))
{
rotate(fa);
}
else
{
rotate(x);
}
}
}
root=x;
return ;
}
void insert(int x)
{
if (root==0)
{
root=++cnt;
val[root]=x;
size[root]=sum[root]=1;
son[root][0]=son[root][1]=0;
return ;
}
int now=root,fa=0;
while (1)
{
if (val[now]==x)
{
sum[now]++;
update(now);
update(fa);
splay(now);
return ;
}
fa=now,now=son[now][x>val[now]];
if (now==0)
{
cnt++;
val[cnt]=x;
size[cnt]=sum[cnt]=1;
father[cnt]=fa;
son[fa][x>val[fa]]=cnt;
update(fa);
splay(cnt);
return ;
}
}
}
int find_rank(int x)
{
int now=root,ans=0;
while (1)
{
if (x<val[now])
{
now=son[now][0];
continue;
}
ans+=size[son[now][0]];
if (x==val[now])
{
splay(now);
return ans+1;
}
ans+=sum[now];
now=son[now][1];
}
}
int find_num(int x)
{
int now=root;
while (1)
{
if (son[now][0]&&x<=size[son[now][0]])
{
now=son[now][0];
continue;
}
if (son[now][0])
{
x-=size[son[now][0]];
}
if (x<=sum[now])
{
splay(now);
return val[now];
}
x-=sum[now];
now=son[now][1];
}
}
int pre()
{
int now=son[root][0];
while (son[now][1])
{
now=son[now][1];
}
return now;
}
int suf()
{
int now=son[root][1];
while (son[now][0])
{
now=son[now][0];
}
return now;
}
inline void del(int x)
{
find_rank(x);
if (sum[root]>1)
{
sum[root]-=1;
update(root);
return ;
}
if (son[root][0]==0&&son[root][1]==0)
{
clear(root);
root=0;
return ;
}
if (son[root][0]==0)
{
int tmp=root;
father[root=son[root][1]]=0;
clear(tmp);
return ;
}
if (son[root][1]==0)
{
int tmp=root;
father[root=son[root][0]]=0;
clear(tmp);
return ;
}
int tmp=root,Pre=pre();
splay(Pre);
connect(son[tmp][1],root,1);
clear(tmp);
update(root);
return ;
}
int main()
{
n=read(),m=read();
int cnt=0;
for (int i=1;i<=n;i++)
{
int x=read();
insert(x);
}
while (m--)
{
int opt,k;
opt=read(),k=read();
k^=last;
if ( opt==1)
{
insert(k);
}
if (opt==2)
{
del(k);
}
if (opt==3)
{
insert(k);
last=find_rank(k);
del(k);
ans^=last;
}
if (opt==4)
{
last=find_num(k);
ans^=last;
}
if (opt==5)
{
insert(k);
last=val[pre()];
ans^=last;
del(k);
}
if (opt==6)
{
insert(k);
last=val[suf()];
ans^=last;
del(k);
}
}
cout<<ans<<"\n";
return 0;
}
by Smile_Cindy @ 2020-02-27 22:22:02
@谦谦君子
开O2
为啥你们的erase都写得这么麻烦?
我的erase
void erase(int x)
{
int pre=prev(x),nxt=next(x);
splay(pre);
splay(nxt,pre);
int t=ch[nxt][0];
if(cnt[t]>1)
{
cnt[t]--;
splay(t);
}
else ch[nxt][0]=0;
}
by 1kri @ 2020-02-27 22:25:46
这么友好毒瘤的数据fhq-treap是没救了吗
by Froggy @ 2020-02-27 22:32:26
@L_C_A
by 1kri @ 2020-02-27 22:33:26
@Froggy 真的,辣我再码一遍,谢谢
by gyh20 @ 2020-02-27 22:43:14
这道题应该不卡,我之前过不了是写错了
by Skyjoy @ 2020-02-27 22:44:48
qndmx
by Polaris_Dane @ 2020-02-27 22:53:33
不卡,我6s多过了
by Minecraft万岁 @ 2020-02-27 23:00:17
Splay跑起来应该很快啊
by 谦谦君子 @ 2020-02-28 21:27:33
@Froggy 我已经用fhqA了qaq,只是发现Splay过不了,但是其实splay效率也还不错吧
by 谦谦君子 @ 2020-02-28 21:28:15
@L_C_A fhq可以过啊qaq