# [BZOJ]4998: 星球联盟

题解: LCT+并查集  查询环上元素个数

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <set>
#include <map>
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
const int MAXN=3e5+10;
const double eps=1e-8;
#define ll long long
using namespace std;
struct edge{int t,v;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return x*f;
}

int f[MAXN];
int find1(int x){
if(x==f[x])return x;
return f[x]=find1(f[x]);
}
int pre[MAXN],ch[MAXN][2],res[MAXN],sz[MAXN];
bool rt[MAXN];
void newnode(int t){
pre[t]=ch[t][0]=ch[t][1]=res[t]=0;rt[t]=1;
}

void reverse(int x){
if(!x)return ;
swap(ch[x][0],ch[x][1]);
res[x]^=1;
}

void push(int x){
if(res[x]){
reverse(ch[x][0]);
reverse(ch[x][1]);
res[x]^=1;
}
}

void P(int x){
if(!rt[x])P(find1(pre[x]));
push(x);
}

void rotate(int x,int kind){
int y=find1(pre[x]);
ch[y][!kind]=ch[x][kind];pre[ch[x][kind]]=y;
if(rt[y])rt[x]=1,rt[y]=0;
else ch[find1(pre[y])][ch[find1(pre[y])][1]==y]=x;
pre[x]=find1(pre[y]);ch[x][kind]=y;pre[y]=x;
}

void splay(int x){
P(x);
while(!rt[x]){
if(rt[find1(pre[x])])rotate(x,ch[find1(pre[x])][0]==x);
else{
int y=find1(pre[x]);int kind=ch[find1(pre[y])][0]==y;
if(ch[y][kind]==x)rotate(x,!kind),rotate(x,kind);
else rotate(y,kind),rotate(x,kind);
}
}
}

void access(int x){
int y=0;
while(x){
splay(x);
if(ch[x][1])pre[ch[x][1]]=x,rt[ch[x][1]]=1,ch[x][1]=0;
if(y)rt[y]=0;
ch[x][1]=y;
y=x;x=find1(pre[x]);
}
}

void mroot(int x){access(x);splay(x);reverse(x);}
x=find1(x);y=find1(y);
mroot(x);mroot(y);
pre[x]=y;
}

bool pd(int u,int v){
u=find1(u);v=find1(v);
while(pre[u])u=find1(pre[u]);
while(pre[v])v=find1(pre[v]);
return u==v;
}

int st[MAXN],tot;

void dfs(int x){
if(!x)return ;
st[++tot]=x;push(x);
dfs(ch[x][0]);
dfs(ch[x][1]);
}

void Tarjan(int u,int v){
u=find1(u);v=find1(v);
if(u==v)return ;
mroot(u);access(v);splay(v);
tot=0;dfs(v);
inc(i,2,tot){
int t1=find1(st[i-1]);
int t2=find1(st[i]);
if(t1==t2)continue;
f[t2]=t1;sz[t1]+=sz[t2];
}
inc(i,1,tot)ch[st[i]][0]=ch[st[i]][1]=pre[st[i]]=0,rt[st[i]]=1;
}

int main(){
inc(i,1,n)newnode(i),f[i]=i,sz[i]=1;
int u,v;
inc(i,1,m){
else Tarjan(u,v);
}
inc(i,1,q){
else{
Tarjan(u,v);
int t1=find1(u);
printf("%d\n",sz[t1]);
}
}
}


## 4998: 星球联盟

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 329  Solved: 195
[Submit][Status][Discuss]

1≤N,M,P≤200000

5 3 4
1 2
4 3
4 5
2 3
1 3
4 5
2 4

No
3
2
5

## HINT

posted @ 2019-02-17 21:33  wang9897  阅读(309)  评论(0编辑  收藏  举报