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. Spring 源码学习(一)-容器的基础结构

    关注公众号,大家可以在公众号后台回复“博客园”,免费获得作者 Java 知识体系/面试必看资料 展示的代码摘取了一些核心方法,去掉一些默认设置和日志输出,还有大多数错误异常也去掉了,小伙伴想看详细代码 ...

  2. HttpClientFactory 使用说明 及 对 HttpClient 的回顾和对比

    目录 HttpClient 日常使用及坑点: HttpClientFactory 优势: HttpClientFactory 使用方法: 实战用法1:常规用法 1. 在 Startup.cs 中进行注 ...

  3. LeetCode :1.两数之和 解题报告及算法优化思路

    最近开始重拾算法,在 LeetCode上刷题.顺便也记录下解题报告以及优化思路. 题目链接:1.两数之和 题意 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 ...

  4. asp.net core系列 69 Amazon S3 资源文件上传示例

    一.  上传示例 Install-Package AWSSDK.S3 -Version 3.3.104.10 using Amazon; using Amazon.Runtime; using Ama ...

  5. k8s+istio:流量控制之灰度发布

    通过Kubernetes+Istio的流量控制实现灰度发布,主要演示通过流量权重实现蓝绿,通过http自定义头实现金丝雀 准备环境 k8s和istio不想自己装的话可以在云上买个按量付费集群,用完即删 ...

  6. manifest.json 解析--手机web app开发笔记(三-2)

    四.SDK配置和模块权限配置 SDK 就是 Software Development Kit 的缩写,中文意思就是“软件开发工具包”,也就是辅助开发某一类软件的相关文档.范例和工具的集合都可以叫做“S ...

  7. egg 自学入门demo分享

    目录 安装 项目 连接数据库 编写model 编写controller 添加路由 2018-08,本文适用于对egg有兴趣想要了解的同学 完整项目代码:https://github.com/NameH ...

  8. 9个tcpdump使用实例

    tcpdump能帮助我们捕捉并保存网络包,保存下来的网络包可用于分析网络负载情况,包可通过tcpdump命令解析,也可以保存成后缀为pcap的文件,使用wireshark等软件进行查看. 以下将给出9 ...

  9. android ——通知管理

    public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle saved ...

  10. Rootkit与后门隐藏技术

    目录 简介 linux虚拟文件系统VFS rootkit的功能 隐藏文件 基本方法 高级方法 系统调用流程 hook sys_getdents sys_getdents的调用树 最底层的方法 隐藏进程 ...