虽然过了,但是有好几个点都是900+ms,应该是LCT哪个地方写错了?毕竟我看大佬们这个题都跑了总共不到1s啊。
代码:
#include<iostream>
#include<cstdio>
#include<stack>
using namespace std;
const int N=2e5+13;
struct LCT{
int fa[N],ch[N][2],siz[N];bool tag[N];
inline void refresh(int x){siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;}
inline bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
inline bool chk(int x){return ch[fa[x]][1]==x;}
inline void rotate(int now){
int f=fa[now],gf=fa[f],k=chk(now),w=ch[now][k^1];
fa[now]=gf;if(!isroot(f)) ch[gf][chk(f)]=now;
if(w) fa[w]=f;ch[f][k]=w;
fa[f]=now;ch[now][k^1]=f;
refresh(f),refresh(now);
}
inline void pushdown(int x){
if(!tag[x]) return;
tag[ch[x][0]]^=1,tag[ch[x][1]]^=1;
swap(ch[x][0],ch[x][1]);
tag[x]=0;
}
inline void splay(int now){
stack<int> st;
int p=now;
while(!isroot(p)) st.push(p),p=fa[p];
st.push(p);
while(!st.empty()) pushdown(st.top()),st.pop();
while(!isroot(now)){
int f=fa[now],gf=fa[f];
if(!isroot(f)){
if(chk(f)==chk(now)) rotate(f);
else rotate(now);
}
rotate(now);
}
}
inline void access(int x){
for(int p=0;x;p=x,x=fa[x]) splay(x),ch[x][1]=p,refresh(x);
}
inline void makeroot(int x){
access(x);splay(x);
tag[x]^=1;
}
inline int findroot(int x){
access(x);splay(x);
while(ch[x][0]) x=ch[x][0];
return x;
}
inline void split(int x,int y){
makeroot(x);
access(y);splay(y);
}
inline void link(int x,int y){
makeroot(x);
if(findroot(y)!=x) fa[x]=y;
}
inline void cut(int x,int y){
split(x,y);
if(ch[y][0]==x&&!ch[x][1]) ch[y][0]=0,fa[x]=0;
}
}T;
int n,m,k[N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%d",&k[i]);
if(i+k[i]>n) T.link(i,n+1);
else T.link(i,i+k[i]);
}
scanf("%d",&m);
while(m--){
int op,x,y;
scanf("%d%d",&op,&x);++x;
if(op==1){
T.split(x,n+1);
printf("%d\n",T.siz[n+1]-1);
}
else{
scanf("%d",&y);
if(x+k[x]>n) T.cut(x,n+1);
else T.cut(x,x+k[x]);
if(x+y>n) T.link(x,n+1);
else T.link(x,x+y);
k[x]=y;
}
}
return 0;
}
我猜或许是某个操作没有做使得splay没法保证均摊复杂度?求助各位巨佬,感激不尽!