LCT 板子太慢怎么办
  • 板块学术版
  • 楼主serene_analysis
  • 当前回复9
  • 已保存回复9
  • 发布时间2022/11/22 21:19
  • 上次更新2023/10/27 01:54:03
查看原帖
LCT 板子太慢怎么办
293810
serene_analysis楼主2022/11/22 21:19

rt。这里的太慢指的是板子题用时几乎是同学的 1.51.5 倍。求助是我哪里写假了还是别的原因。(注:我的 splay 水平仅限于知道原理并且能写出来 LCT 用的板子,因此如果是 splay 的原因您直接告诉我怎么改就好)

本身写啥常数都大,万一考场上写了被卡常遗恨千年,因此来求助。

代码如下。

#include<algorithm>
#include<cstdio>
#include<vector>
const int maxn=1e5+5;
struct node{
	bool turn;
	int fa,ch[2],val;
	#define l ch[0]
	#define r ch[1]
}tree[maxn];
int v[maxn];
void update(int i){
	tree[i].val=tree[tree[i].l].val^tree[tree[i].r].val^v[i];
	return;
}
void con(int x,int f,int tp){
	tree[f].ch[tp]=x,tree[x].fa=f;
	return;
}
bool isroot(int x){return tree[tree[x].fa].l!=x&&tree[tree[x].fa].r!=x;}
int ident(int x){return tree[tree[x].fa].l==x?0:1;}
void pushdown(int x){
	if(tree[x].turn){
		std::swap(tree[x].l,tree[x].r);
		tree[tree[x].l].turn^=1,tree[tree[x].r].turn^=1;
		tree[x].turn=false;
	}
	return;
}
void rotate(int x){
	int f=tree[x].fa,ff=tree[f].fa,fson=ident(x),ffson=ident(f),d=tree[x].ch[fson^1];
	tree[x].fa=ff;
	if(!isroot(f))con(x,ff,ffson);
	con(d,f,fson),con(f,x,fson^1);
	update(f),update(x);
	return;
}
int stk[maxn],scnt;
void splay(int x){
	int y=x;
	stk[scnt=1]=y;
	while(!isroot(y))y=tree[y].fa,stk[++scnt]=y;
	while(scnt)pushdown(stk[scnt--]);
	for(int y=tree[x].fa;!isroot(x);y=tree[x].fa){
		if(!isroot(y))rotate(ident(x)==ident(y)?y:x);
		rotate(x);
	}
	return;
}
void access(int x){
	for(int y=0;x;x=tree[y].fa)splay(x),tree[x].r=y,update(y=x);
	return;
}
void maker(int x){
	access(x),splay(x),tree[x].turn^=true,pushdown(x);
	return;
}
void road(int x,int y){
	maker(x),access(y),splay(y);
	return;
}
int findr(int x){
	access(x),splay(x);
	while(tree[x].l)x=tree[x].l,pushdown(x);
	return x;
}
void link(int x,int y){
	road(x,y);
	if(findr(y)!=x)tree[x].fa=y;
	return;
}
void cut(int x,int y){
	road(x,y);
	if(tree[y].l==x&&!tree[x].r)tree[y].l=tree[x].fa=0,update(y);
	return;
}
#undef l
#undef r
int n,m;
signed main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%d",v+i);
	for(int i=1;i<=m;i++){
		int opt,x,y;
		scanf("%d%d%d",&opt,&x,&y);
		if(opt==0)road(x,y),printf("%d\n",tree[y].val);
		else if(opt==1)link(x,y);
		else if(opt==2)cut(x,y);
		else splay(x),v[x]=y;
	}
	return 0;
}
2022/11/22 21:19
加载中...