题目:
这是一道模板题。
维护一个 nn 点的无向图,支持:
- 加入一条连接 uu 和 vv 的无向边
- 查询 uu 和 vv 的连通性
由于本题数据较大,因此输出的时候采用特殊的输出方式:用 00 或 11 代表每个询问的答案,将每个询问的答案依次从左到右排列,把得到的串视为一个二进制数,输出这个二进制数 \text{mod} ~ 998244353mod 998244353 的值。
请务必使用快读。
并查集模板:
void init() {
for (int i = 1; i <= n; ++i) {
father[i] = i;
}
}//定义father数组
int get(int x) {
if (father[x] == x)
return x;
else
return father[x] = get(father[x]);
}//路径压缩并查找父节点
void merge(int x, int y) {
x = get(x);
y = get(y);
if (x != y) {
father[y] = x;
}
}//并集
其他模板:
/*inline int read() {
char ch = getchar(); int x = 0, f = 1;
while(ch < '0' || ch > '9') {
if(ch == '-') f = -1;
ch = getchar();
} while('0' <= ch && ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
} return x * f;
}//快读函数 */
/*long long int change(string str)
{
bitset<32> b(str);
long long int n;
n=b.to_ulong()%998244353;
return n%998244353;
}//将01串转换成long long int数字 */
被题目误导了,其实这两个模板不用也能过,用了反而会出大问题,不过也是借这个题一起把这两个模板学了,不亏
AC代码:
#include <iostream>
#include <bitset>
#include <string>
using namespace std;
typedef long long ll;
const int N = 8e7+9;
const int mod=998244353;
int n,m;
long long ans=0;
int father[N] = {0};
void init() {
for (int i = 1; i <= n; ++i) {
father[i] = i;
}
}//定义father数组
int get(int x) {
if (father[x] == x)
return x;
else
return father[x] = get(father[x]);
}//路径压缩并查找父节点
void merge(int x, int y) {
x = get(x);
y = get(y);
if (x != y) {
father[y] = x;
}
}//并集
int main(){
scanf("%d %d",&n,&m);
init();
for(int i = 1;i <= m;i++){
int z,x,y;
scanf("%d %d %d",&z,&x,&y);
if(z == 0){
merge(x,y);
}
if(z == 1){
if(get(x)==get(y))
{
ans*=2;
ans++;
ans%=mod;
}
if(get(x)!=get(y))
{
ans*=2;
ans%=mod;
}
}
}
printf("%lld",ans%mod);
return 0;
}