[BZOJ]4998: 星球联盟

编程入门 行业动态 更新时间:2024-10-18 12:20:21

[BZOJ]4998: <a href=https://www.elefans.com/category/jswz/34/1760928.html style=星球联盟"/>

[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 link(x) for(edge *j=h[x];j;j=j->next)
#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;
void add(int x,int y,int vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;}
ll read(){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);}
void Link(int x,int y){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(){int n=read();int m=read();int q=read();inc(i,1,n)newnode(i),f[i]=i,sz[i]=1;int u,v;inc(i,1,m){u=read();v=read();if(!pd(u,v))Link(u,v);else Tarjan(u,v);}inc(i,1,q){u=read();v=read();if(!pd(u,v))printf("No\n"),Link(u,v);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]

Description

在遥远的S星系中一共有N个星球,编号为1…N。其中的一些星球决定组成联盟,以方便相互间的交流。但是,组成 联盟的首要条件就是交通条件。初始时,在这N个星球间有M条太空隧道。每条太空隧道连接两个星球,使得它们能 够相互到达。若两个星球属于同一个联盟,则必须存在一条环形线路经过这两个星球,即两个星球间存在两条没有 公共隧道的路径。为了壮大联盟的队伍,这些星球将建设P条新的太空隧道。这P条新隧道将按顺序依次建成。一条 新轨道建成后,可能会使一些星球属于同一个联盟。你的任务是计算出,在一条新隧道建设完毕后,判断这条新轨 道连接的两个星球是否属于同一个联盟,如果属于同一个联盟就计算出这个联盟中有多少个星球。

 

Input

第1行三个整数N,M和P,分别表示总星球数,初始时太空隧道的数目和即将建设的轨道数目。 第2至第M+1行,每行两个整数,表示初始时的每条太空隧道连接的两个星球编号。 第M+2行至第M+P+1行,每行两个整数,表示新建的太空隧道连接的两个星球编号。 这些太空隧道按照输入的顺序依次建成。 1≤N,M,P≤200000

 

Output

输出共P行。 如果这条新的太空隧道连接的两个星球属于同一个联盟,就输出一个整数,表示这两个星球所在联盟的星球数。 如果这条新的太空隧道连接的两个星球不属于同一个联盟,就输出"No"(不含引号)。

 

Sample Input

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

Sample Output

No
3
2
5

HINT

 


 

 

转载于:.html

更多推荐

[BZOJ]4998: 星球联盟

本文发布于:2024-02-07 02:40:33,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1752569.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:星球   联盟   BZOJ

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!