Eddy2008 @ 2022-02-08 10:59:17
如题,参考这篇博文写的,结果跑出了14.79秒的良好成绩。请问这正常吗?是我常数太大了吗?
代码:
#include<bits/stdc++.h>
#define maxn 1100010
using namespace std;
inline 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;
}
int n,m;
struct Splay{
int root=0,tol=0,fa[maxn],ch[maxn][2],val[maxn],cnt[maxn],siz[maxn];
inline void update(int x){siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+cnt[x];}
inline bool get(int x){return x==ch[fa[x]][1];}
inline void rotate(int x){
int y=fa[x],z=fa[y],chk=get(x);
ch[y][chk]=ch[x][!chk], fa[ch[x][!chk]]=y;
ch[x][!chk]=y, fa[y]=x;
fa[x]=z, ch[z][y==ch[z][1]]=x;
update(y);
}
inline void splay(int x){
for(int p=fa[x];p;rotate(x), p=fa[x])
if(fa[p]) rotate(get(x)==get(p) ? p : x);
root=x;
}
inline void insert(int v){
if(!root){
val[++tol]=v, cnt[tol]=1;
root=tol, update(tol);
return;
}
int p=root,f=0;
while(1){
if(val[p]==v){
cnt[p]++;
update(p), update(f);
splay(p);
return;
}
f=p, p=ch[p][v>val[p]];
if(!p){
val[++tol]=v, cnt[tol]++;
fa[tol]=f, ch[f][v>val[f]]=tol;
update(tol), update(f);
splay(tol);
return;
}
}
}
inline int getrank(int v){
int p=root,ans=0;
while(1){
if(v<val[p]) p=ch[p][0];
else{
ans+=siz[ch[p][0]];
if(val[p]==v){splay(p); return ans+1;}
ans+=cnt[p], p=ch[p][1];
}
}
}
inline int getval(int k){
int p=root;
while(1){
if(ch[p][0] && siz[ch[p][0]]>=k) p=ch[p][0];
else{
k-=siz[ch[p][0]];
if(k<=cnt[p]){splay(p); return val[p];}
k-=cnt[p], p=ch[p][1];
}
}
}
inline int pre(){
int p=ch[root][0];
while(ch[p][1]) p=ch[p][1];
if(p) splay(p);
return p;
}
inline int nxt(){
int p=ch[root][1];
while(ch[p][0]) p=ch[p][0];
if(p) splay(p);
return p;
}
inline void remove(int v){
getrank(v);
if(cnt[root]>1) cnt[root]--, update(root);
else if(!ch[root][0] && !ch[root][1]) root=0;
else if(!ch[root][0]) root=ch[root][1], fa[root]=0;
else if(!ch[root][1]) root=ch[root][0], fa[root]=0;
else{
int p=root; root=pre();
fa[ch[p][1]]=root, ch[root][1]=ch[p][1];
update(root);
}
}
};
Splay T;
int main(){
n=read(), m=read();
for(int i=1;i<=n;i++) T.insert(read());
int ans=0,last=0;
for(int i=1,op,x;i<=m;i++){
op=read(), x=read();
x=x^last;
if(op==1) T.insert(x);
else if(op==2) T.remove(x);
else if(op==3){
T.insert(x);
last=T.getrank(x);
T.remove(x);
ans^=last;
}
else if(op==4){
last=T.getval(x);
ans^=last;
}
else if(op==5){
T.insert(x);
last=T.val[T.pre()];
T.remove(x);
ans^=last;
}
else if(op==6){
T.insert(x);
last=T.val[T.nxt()];
T.remove(x);
ans^=last;
}
}
printf("%d",ans);
return 0;
}
by RuSun @ 2022-02-08 11:08:59
同 splay
我的
by eigw22h619 @ 2022-02-08 20:51:38
不太正常,可能是因为你的操作3、5、6都调用了3个函数。我的 splay 6.66s。