https://ac.nowcoder.com/acm/contest/368/D

题意

小T有n个点,每个点可能是黑色的,可能是白色的。
小T对这张图的定义了白连通块和黑连通块:
白连通块:图中一个点集V,若满足所有点都是白点,并且V中任意两点都可以只经过V中的点互相到达,则称V中的点构成了一个白连通块。
黑连通块:类似白连通块的定义。
小T对这n个点m次操作。
1、在两个点之间连一条边。
2、询问白(黑)连通块个数。
3、给出x,y两个点,保证同色(为了方便描述,x,y都是白点,黑色同理)。询问存在多少个黑点,将它改变颜色后,x,y所在的白连通块会合并为一个。如果x,y已经在一个白连通块内了,输出-1。(注意:这里不会对点的颜色改变,只统计个数)

思路

感觉这个并查集还是很妙的,颜色相同的想要合并就按照正常的并查集来。如果颜色不同,直接合并没有意义,用bitset记录下来,两个白点如果bitset中有相同的黑点,那么这个点就是第三问中的一个合法点。

#include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <cassert> /* ⊂_ヽ
  \\ Λ_Λ 来了老弟
   \('ㅅ')
    > ⌒ヽ
   /   へ\
   /  / \\
   レ ノ   ヽ_つ
  / /
  / /|
 ( (ヽ
 | |、\
 | 丿 \ ⌒)
 | |  ) /
'ノ )  Lノ */ using namespace std;
#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "\n";
#define pb push_back
#define pq priority_queue typedef long long ll;
typedef unsigned long long ull;
//typedef __int128 bll;
typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;
typedef pair<int,pii> p3; //priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
//#define endl '\n' #define boost ios::sync_with_stdio(false);cin.tie(0)
#define rep(a, b, c) for(int a = (b); a <= (c); ++ a)
#define max3(a,b,c) max(max(a,b), c);
#define min3(a,b,c) min(min(a,b), c); const ll oo = 1ll<<;
const ll mos = 0x7FFFFFFF; //
const ll nmos = 0x80000000; //-2147483648
const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f; //
const int mod = 1e9+;
const double esp = 1e-;
const double PI=acos(-1.0);
const double PHI=0.61803399; //黄金分割点
const double tPHI=0.38196601; template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
} inline void cmax(int &x,int y){if(x<y)x=y;}
inline void cmax(ll &x,ll y){if(x<y)x=y;}
inline void cmin(int &x,int y){if(x>y)x=y;}
inline void cmin(ll &x,ll y){if(x>y)x=y;} /*-----------------------showtime----------------------*/ const int maxn = 5e4+;
int col[maxn],fa[maxn];
bitset<> b[maxn],tmp;
int ans[];
int find(int x){
if(fa[x] == x) return x;
return fa[x] = find(fa[x]);
}
void uni(int x,int y){
int fx = find(x), fy = find(y);
if(col[x] == col[y]){
if(fx != fy){
fa[fx] = fy;
ans[col[x]]--;
b[fy] |= b[fx];
}
}
else b[fx].set(y), b[fy].set(x);
} void cal(int x,int y){
int fx = find(x), fy = find(y);
if(fx == fy) puts("-1");
else {
tmp = b[fx] & b[fy];
printf("%d\n", (int)tmp.count());
}
}
int main(){
int n,m;
scanf("%d%d", &n, &m);
rep(i, , n) scanf("%d", &col[i]), fa[i] = i, ans[col[i]] ++;
while(m--){
int op; scanf("%d", &op);
if(op == ) {
int x, y; scanf("%d%d", &x, &y);
uni(x, y);
}
else if(op == ) {
int x; scanf("%d", &x);
printf("%d\n", ans[x]);
}
else {
int x,y; scanf("%d%d", &x, &y);
cal(x, y);
}
}
return ;
}

牛客练习赛39 D 动态连通块+并查集 X bitset 优化的更多相关文章

  1. 牛客练习赛16 C 任意点【并查集/DFS/建图模型】

    链接:https://www.nowcoder.com/acm/contest/84/C 来源:牛客网 题目描述 平面上有若干个点,从每个点出发,你可以往东南西北任意方向走,直到碰到另一个点,然后才可 ...

  2. 牛客练习赛39 B.选点

    链接:https://ac.nowcoder.com/acm/contest/368/B 来源:牛客网 题目描述 有一棵n个节点的二叉树,1为根节点,每个节点有一个值wi.现在要选出尽量多的点. 对于 ...

  3. 牛客练习赛39 B:选点(二叉树遍历+LIS)

    链接: https://ac.nowcoder.com/acm/contest/368/B 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 131072K,其他语言262 ...

  4. PAT天梯赛练习题——L3-004. 肿瘤诊断(三维连通块并查集)

    L3-004. 肿瘤诊断 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 在诊断肿瘤疾病时,计算肿瘤体积是很重要的一环.给定病灶 ...

  5. LightOJ——1012Guilty Prince(连通块并查集)

    1012 - Guilty Prince Time Limit: 2 second(s) Memory Limit: 32 MB Once there was a king named Akbar. ...

  6. 牛客小白月赛28 J.树上行走 (并查集,dfs)

    题意:有\(n\)个点,\(n-1\)条边,每个点的类型是\(0\)或\(1\),现在让你选一个点,然后所有与该点类型不同的点直接消失,问选哪些点之后,该点所在的联通块最大. 题解: 因为选完之后两个 ...

  7. 牛客网-Beauty of Trees 【加权并查集】

    锟斤拷锟接o拷https://www.nowcoder.com/acm/contest/119/A锟斤拷源锟斤拷牛锟斤拷锟斤拷 锟斤拷目锟斤拷锟斤拷 It锟斤拷s universally acknow ...

  8. UVA 572 油田连通块-并查集解决

    题意:8个方向如果能够连成一块就算是一个连通块,求一共有几个连通块. 分析:网上的题解一般都是dfs,但是今天发现并查集也可以解决,为了方便我自己理解大神的模板,便尝试解这道题目,没想到过了... # ...

  9. 牛客练习赛39 C 流星雨 (概率dp)

    题意: 现在一共有n天,第i天如果有流星雨的话,会有wi颗流星雨. 第1天有流星雨的概率是p1. 如果第i−1 (i≥2)天有流星雨,第i天有流星雨的可能性是pi+P,否则是pi. 求n天后,流星雨颗 ...

随机推荐

  1. 「玩转Python」打造十万博文爬虫篇

    前言 这里以爬取博客园文章为例,仅供学习参考,某些AD满天飞的网站太浪费爬虫的感情了. 爬取 使用 BeautifulSoup 获取博文 通过 html2text 将 Html 转 Markdown ...

  2. Eclipse "Adb failed to restart !"

    今天遇到这个问题,如图所示: 上网找了下,原来是电脑上的各种手机助手抢占了手机链接.http://blog.csdn.net/zhufuing/article/details/19398125 说得很 ...

  3. hdoj 4706 Children's Day

    题目意思就是用a-z组成一个N,然后到z后又跳回a,输出宽从3到10的N. #include <stdio.h> #include <string.h> char s[14][ ...

  4. 曹工杂谈:Linux服务器上,Spring Boot 原地修改 jar 包配置文件/替换class文件,免去重复上传的麻烦

    一.前言 相信很多同学有这样的需求,现在很多公司都有多地的研发中心,经常需要跨地区部署,比如,博主人在成都,但是服务器是北京的.一般城市间网络都不怎么好,上传一个几十兆的jar包那是真的慢,别说现在微 ...

  5. Redis Sentinel基本实现原理

    一.出现的背景: Redis 主从复制模式下一旦主节点由于故障不能提供服务,需要人工将从节点晋升为主节点,同时还要通知应用方更新主节点地址,对于很多应用这种场景的这种故障处理方式是非常浪费人力的.为了 ...

  6. SWT 注意事项

    一:GridData (1) 将 GridData 的 widthHint 设置为0,可以解决控件大小会随着这其默认值长度大小而改变的问题.

  7. Go slice:切片的“陷阱”和本质

    文章说明 总结了go语言中切片slice的特殊性和使用时的注意事项. 个人理解,不足之处欢迎指出. slice:切片,是go语言中一种常用的数据结构,基于数组构建,表示相同数据类型的集合. 数组 Go ...

  8. 夯实Java基础(十四)——Java8新的日期处理类

    1.前言 Java8之前处理日期一直是Java程序员比较头疼的问题,从Java 8之后,Java里面添加了许多的新特性,其中一个最常见也是最实用的便是日期处理的类——LocalDate.LocalDa ...

  9. Java ActionListenner类的一些理解

    Java的ActionListenner事实上我去年年这个时候大概就已经接触到了,也学会了比较简单的使用.但却始终不能理解ActionListenner的一系列的运行是怎么维持这么一个联系的? 我产生 ...

  10. python案例:使用if语句实现一个猜拳游戏

    任务要求: 在控制台中提示输入石头.剪刀.布,按回车键,然后给出游戏结果. 分析: 我们知道在游戏规则中,石头克剪刀,剪刀克布,布克石头.但是这在计算机中并不是很好直接的表示,因此我们分别用0.1.2 ...