关于LCT的时间复杂度
查看原帖
关于LCT的时间复杂度
145119
WhiteLabs楼主2021/9/4 18:49

此题 n=5e5,q=5e6n=5e5,q=5e6 ,按LCT的复杂度计算,5e6log(5e5)5e6*log(5e5),理论上时间复杂度正确,应当能满足3S的时限。但求助为什么还是有三个点TLE了...常数在大也不应该慢成这样啊... 代码:

#include <bits/stdc++.h>
using namespace std;

inline int read(){
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch&15);ch=getchar();}
	return x*f;
}

const int N=5e5+7;

int n,q;
long long ans;

struct S{
	S *ls,*rs,*fa;int val,size,rev;
	inline bool get(){return fa->ls==this;}
	inline bool isrt(){return fa->ls!=this&&fa->rs!=this;}
	inline void pushUp(){size=ls->size+rs->size+1;}
	inline void reverse(){swap(ls,rs);rev^=1;}
	inline void pushDown(){if(!rev)return;ls->reverse();rs->reverse();rev=0;}
}tree[N],*null=tree;
inline void rotate(S *x){
	bool f=!x->get();S *SN=f?x->ls:x->rs,*FA=x->fa,*GF=FA->fa;
	if(!FA->isrt()) FA->get()?GF->ls=x:GF->rs=x;x->fa=GF;
	SN->fa=FA;f?FA->rs=SN:FA->ls=SN;FA->fa=x;f?x->ls=FA:x->rs=FA;
	FA->pushUp();x->pushUp();
}
void pushAll(S *x){if(!x->isrt())pushAll(x->fa);x->pushDown();}
void splay(S *x){
	for(pushAll(x);!x->isrt();rotate(x))
		if(!x->fa->isrt()) rotate(x->fa->get()==x->get()?x->fa:x);
}
inline void maketree(S *x,int num){x->fa=x->ls=x->rs=null;x->size=1;x->val=num;}
inline void access(S *x){
	for(S *last=null;x!=null;last=x,x=x->fa)
		splay(x),x->rs=last,x->pushUp();
}
inline void makert(S *x){
	access(x);splay(x);
	x->reverse();
}
inline S *findrt(S *x){
	access(x);splay(x);
	while(x->ls!=null) x->pushDown(),x=x->ls;splay(x);
	return x;
}
void link(S *x,S *y){
	makert(x);
	if(findrt(y)!=x) x->fa=y;
}
void cut(S *x,S *y){
	makert(x);
	if(findrt(y)==x&&y->fa==x&&y->ls==null)
		x->rs=y->fa=null,x->pushUp();
}

S *getKth(S *x,int k){
	while(1){
//		cout<<k<<' '<<x->val<<' '<<x->ls->size<<endl;
		if(k>x->ls->size+1) k-=x->ls->size+1,x=x->rs;
		if(k==x->ls->size+1) return x;
		if(k<x->ls->size+1) x=x->ls;
	}
	exit(0);
}
int query(int X,int k){
	S *x=&tree[X];
	access(x);splay(x);
	return getKth(x,x->size-k)->val;
}

#define ui unsigned int
ui s;

inline ui get(ui x) {
	x ^= x << 13;
	x ^= x >> 17;
	x ^= x << 5;
	return s = x;
}

#undef ui

struct T{int v,next;}edge[N<<1];
int f[N],cnt;
void insert(int u,int v){
	edge[++cnt]=T{v,f[u]};f[u]=cnt;
	edge[++cnt]=T{u,f[v]};f[v]=cnt;
}

int deep[N];
void dfs(int u,int fa){
	deep[u]=deep[fa]+1;
	for(int i=f[u];i;i=edge[i].next){
		int v=edge[i].v;
		if(v^fa) dfs(v,u);
	}
}

int main(){
//	freopen("in","r",stdin);
	n=read(),q=read(),s=read();
	for(int i=1;i<=n;i++) maketree(&tree[i],i);
	int x,root;
	for(int i=1;i<=n;i++){
		x=read();
		if(x) link(&tree[i],&tree[x]),insert(x,i);
		else root=i;
	}
	makert(&tree[root]);
	dfs(root,0);
	int lastans=0,k;
	for(int i=1;i<=q;i++){
		x=(get(s)^lastans)%n+1;
		k=(get(s)^lastans)%deep[x];
		ans^=1ll*i*(lastans=query(x,k));
	}
	printf("%lld\n",ans);
	return 0;
}```
2021/9/4 18:49
加载中...