TLE#8求助
查看原帖
TLE#8求助
236866
401rk8楼主2021/4/7 20:58

rt

不知道是按秩合并挂了还是人傻常数大。。。照着题解改了改也没用

// luogu.P3402 可持久化并查集
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+5;

#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
char buf[1<<20],*p1=buf,*p2=buf;
template<typename T>void read(T &x){
	x=0;int f=1;char c=getchar();
	for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
	for(;isdigit(c);c=getchar())x=x*10-48+c;
	x*=f;
}

int n,m;

int ind,rt[N],ls[N*30],rs[N*30],fa[N*30],dep[N*30];

#define mid (l+r>>1)
void build(int &u,int l,int r) {
	u = ++ind;
	if( l == r ) { fa[u] = l; return; }
	build(ls[u],l,mid), build(rs[u],mid+1,r);
}
void merge(int lst,int &u,int l,int r,int pos,int f) {
	u = ++ind, ls[u] = ls[lst], rs[u] = rs[lst];
	if( l == r ) {
		fa[u] = f, dep[u] = dep[lst];
		return;
	}
	if( pos <= mid ) merge(ls[lst],ls[u],l,mid,pos,f);
	else merge(rs[lst],rs[u],mid+1,r,pos,f);
}
void up(int u,int l,int r,int pos) {
	if( l == r ) { ++dep[u]; return; }
	if( pos <= mid ) up(ls[u],l,mid,pos);
	else up(rs[u],mid+1,r,pos);
}
int query(int u,int l,int r,int pos) {
	if( l == r ) return u;
	if( pos <= mid ) return query(ls[u],l,mid,pos);
	else return query(rs[u],mid+1,r,pos);
}
int find(int root,int pos) {
	int now = query(root,1,n,pos);
	return fa[now]==pos ? now : find(root,fa[now]);
}

int main() {
	read(n),read(m);
	build(rt[0],1,n);
	for(int i = 1; i <= m; ++i) {
		int op,x,y; read(op),read(x);
		if( op == 1 ) {
			read(y);
			rt[i] = rt[i-1];
			int fax = find(rt[i],x), fay = find(rt[i],y);
			if( fa[fax] != fa[fay] ) {
				if( dep[fax] > dep[fay] ) swap(x,y);
				merge(rt[i-1],rt[i],1,n,fa[fax],fa[fay]);
				if( dep[fax] == dep[fay] ) up(rt[i],1,n,fa[fay]);
			}
		} else if( op == 2 ) rt[i] = rt[x];
		else {
			read(y);
			rt[i] = rt[i-1];
			puts(find(rt[i],x)==find(rt[i],y) ? "1" : "0");
		}
	}
	return 0;
}
2021/4/7 20:58
加载中...