MnZn求调LCT
查看原帖
MnZn求调LCT
321529
Remarks楼主2023/12/19 20:08

太痛苦了。。。

经过测试我 splay 中 rotate 操作连续调用了超过 114514 次(?貌似是有地方挂了,应该不是常数的问题/kk

求调求调/dk

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<vector>
using namespace std;
int read(){
	int x=0;
	char ch=getchar();
	while(ch<'0'||ch>'9')ch=getchar();
	while(ch>='0'&&ch<='9'){
		x=(x<<1)+(x<<3)+(ch-'0');
		ch=getchar();
	} 
	return x;
} 
struct point{
	int s[3],fa=0,sz=0,val=0,sum=0;
	int col=0;
}pt[100050];
int n,m;
int get(int p){
	if(pt[pt[p].fa].s[0]==p)return 0;
	if(pt[pt[p].fa].s[1]==p)return 1;
	return 2;
}
void push_up(int p){
	if(p==0)return;
	pt[p].sz=pt[pt[p].s[0]].sz+pt[pt[p].s[1]].sz+1;
	pt[p].sum=pt[pt[p].s[0]].sum|pt[pt[p].s[1]].sum|pt[p].val;
}
void push_down(int p){
	if(pt[p].col){
		pt[pt[p].s[0]].col=pt[p].col;pt[pt[p].s[1]].col=pt[p].col;
		pt[pt[p].s[0]].val=pt[p].col;pt[pt[p].s[1]].val=pt[p].col;
		pt[p].col=0;
	}
}
void update(int p){
	if(get(p)!=2)update(pt[p].fa);
	push_down(p);
}
void rotate(int p){
	int fa=pt[p].fa,op=get(p);
	pt[pt[fa].fa].s[get(fa)]=p;pt[p].fa=pt[fa].fa;
	pt[fa].s[op]=pt[p].s[op^1];pt[pt[p].s[op^1]].fa=fa;
	pt[p].s[op^1]=fa;pt[fa].fa=p;
	push_up(fa);push_up(p);
}
void splay(int p){
	update(p);
	while(get(p)!=2&&get(pt[p].fa)!=2){
		if(get(p)==get(pt[p].fa))rotate(pt[p].fa),rotate(p);
		else rotate(p),rotate(p);
	}
	if(get(p)!=2)rotate(p);	
}
int access(int p){
	int rs=0;
	while(p!=0){
		splay(p);
		pt[p].s[1]=rs;
		push_up(p);
		rs=p;p=pt[p].fa;
	}
	return rs;
}
void link(int x,int y,int c){
	if(x==y)return;
	access(y);splay(y);splay(x);
	if(pt[y].fa!=0)return;
	pt[pt[x].s[0]].fa=pt[x].fa;
	push_up(pt[x].fa);
	pt[x].fa=y;pt[x].val=c;push_up(x);
}
void mdf(int x,int y,int c){
	
	if(x==y)return;
	int lca;access(y);lca=access(x);
	splay(y);splay(x);if(pt[y].fa==0)return;
	if(y==lca){
		splay(lca);
		pt[pt[lca].s[1]].col=c;
		return;
	}
	if(x==lca){
		splay(y);pt[y].col=c;return;
	}
	splay(lca);
	pt[pt[lca].s[1]].col=c;
	pt[y].col=c;
	return;
}
struct pr{
	int ls,rs;
};
pr query(int x,int y){
	if(x==y)return{0,0};
	int lca;access(y);lca=access(x);
	splay(y);splay(x);if(pt[y].fa==0)return {0,0};
	if(y==lca){
		splay(lca);
		return {pt[pt[lca].s[1]].sum,pt[pt[lca].s[1]].sz};
	}
	if(x==lca){
		splay(y);
		return {pt[y].sum,pt[y].sz};
	}
	splay(lca);
	return {pt[pt[lca].s[1]].sum|pt[y].sum,pt[pt[lca].s[1]].sz+pt[y].sz};
}
int pow(int p){
	return (1<<p);
}
int bitcount(int p){
	int ret=0;
	while(p){
		ret++;p=p&(p-1);
	}
	return ret;
}
int main(){
	n=read();m=read();
	for(int i=1;i<=n;i++){
		pt[i].fa=read();
	}
	for(int i=1;i<=n;i++){
		pt[i].val=pow(read());
		push_up(i);
	}
	for(int i=1;i<=m;i++){
		int op=read();
		if(op==1){
			int a=read(),b=read(),c=read();
			link(a,b,pow(c));
		}else if(op==2){
			int a=read(),b=read(),c=read();
			mdf(a,b,pow(c));
		}else if(op==3){
			int a=read(),b=read();
			pr ot=query(a,b);
			printf("%d %d\n",ot.rs,bitcount(ot.ls));
		}
	}
}
2023/12/19 20:08
加载中...