我的LCT为什么跑的这么慢……
查看原帖
我的LCT为什么跑的这么慢……
160484
cunzai_zsy0531kkksd12楼主2021/1/10 21:52

虽然过了,但是有好几个点都是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没法保证均摊复杂度?求助各位巨佬,感激不尽!

2021/1/10 21:52
加载中...