【Codeforces811E】Vladik and Entertaining Flags [线段树][并查集]
Vladik and Entertaining Flags
Time Limit: 20 Sec Memory Limit: 512 MB
Description
n * m的矩形,每个格子上有一个数字代表颜色。
q次询问,询问[l, r]有几个连通块,若颜色相同并且连通则属于同一个连通块。
Input
输入第一行n,m,q。
然后一个n*m的矩形。
之后q行,每行两个整数l,r。
Output
输出q行,对于每个询问输出答案。
Sample Input
1 1 1 1 1
1 2 2 3 3
1 1 1 2 5
4 4 5 5 5
1 5
2 5
1 2
4 5
Sample Output
7
3
4
HINT
Solution
我们运用线段树,线段树一个节点i维护这个点表示的[L, R]。
具体维护Li列~Ri列的连通块个数,Li列连通信息,Ri列连通信息,Li列编号,Ri列编号。
连通信息指的是n个点的连通关系,用一个[10]存下来即可。
我们现在考虑如何合并两个区间。
合并的时候,我们先cnt = 两个区间cnt之和,然后考虑左区间的右端信息 以及 右区间的左端信息。
如果有两个相同的值属于不同连通块,就把它们连通起来,修改一下信息,然后cnt--。显然用并查集处理连通即可。
Code
1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 #include<cstdio> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cmath> 8 using namespace std; 9 typedef long long s64; 10 11 const int ONE = 1000005; 12 const int MOD = 1e9 + 7; 13 14 int get() 15 { 16 int res = 1, Q = 1; char c; 17 while( (c = getchar()) < 48 || c > 57) 18 if(c == '-') Q = -1; 19 if(Q) res = c - 48; 20 while( (c = getchar()) >= 48 && c <= 57) 21 res = res * 10 + c - 48; 22 return res * Q; 23 } 24 25 int n, m, Q; 26 int col[11][ONE]; 27 int l, r; 28 29 int fat[ONE], total = 0; 30 int Find(int x) 31 { 32 if(fat[x] == x) return x; 33 return fat[x] = Find(fat[x]); 34 } 35 36 int Un(int x, int y) 37 { 38 int f1 = Find(x), f2 = Find(y); 39 if(f1 != f2) return fat[f1] = f2, 1; 40 return 0; 41 } 42 43 struct power 44 { 45 int val; 46 int l[11], lid; 47 int r[11], rid; 48 friend power operator +(power a, power b) 49 { 50 power c; 51 c.val = a.val + b.val; 52 c.lid = a.lid, c.rid = b.rid; 53 54 for(int i = 1; i <= n; i++) 55 fat[a.l[i]] = a.l[i], fat[a.r[i]] = a.r[i], 56 fat[b.l[i]] = b.l[i], fat[b.r[i]] = b.r[i]; 57 58 for(int i = 1; i <= n; i++) 59 if(col[i][a.rid] == col[i][b.lid]) 60 c.val -= Un(a.r[i], b.l[i]); 61 62 for(int i = 1; i <= n; i++) 63 c.l[i] = Find(a.l[i]), c.r[i] = Find(b.r[i]); 64 65 return c; 66 } 67 }Node[ONE]; 68 69 void Build(int i, int l, int r) 70 { 71 if(l == r) 72 { 73 Node[i].lid = Node[i].rid = l; 74 for(int j = 1; j <= n; j++) 75 if(col[j - 1][l] != col[j][l]) 76 Node[i].l[j] = Node[i].r[j] = ++total, Node[i].val++; 77 else 78 Node[i].l[j] = Node[i].r[j] = Node[i].l[j - 1]; 79 return; 80 } 81 int mid = l + r >> 1; 82 Build(i << 1, l, mid), Build(i << 1 | 1, mid + 1, r); 83 Node[i] = Node[i << 1] + Node[i << 1 | 1]; 84 } 85 86 power Query(int i, int l, int r, int L, int R) 87 { 88 if(L <= l && r <= R) return Node[i]; 89 90 int mid = l + r >> 1; 91 if(!(mid + 1 <= R)) return Query(i << 1, l, mid, L, R); 92 else if(!(L <= mid)) return Query(i << 1 | 1, mid + 1, r, L, R); 93 else return Query(i << 1, l, mid, L, R) + Query(i << 1 | 1, mid + 1, r, L ,R); 94 } 95 96 int main() 97 { 98 n = get(); m = get(); Q = get(); 99 for(int i = 1; i <= n; i++) 100 for(int j = 1; j <= m; j++) 101 col[i][j] = get(); 102 Build(1, 1, m); 103 104 while(Q--) 105 { 106 l = get(), r = get(); 107 power res = Query(1, 1, m, l, r); 108 printf("%d\n", res.val); 109 } 110 111 }
View Code
转载于:https://www.cnblogs.com/BearChild/p/7768138.html
【Codeforces811E】Vladik and Entertaining Flags [线段树][并查集]相关推荐
- P3273-[SCOI2011]棘手的操作【线段树,并查集】
正题 题目链接:https://www.luogu.com.cn/problem/P3273 题目大意 nnn个点有权值,要求支持操作 连接两个点 单点加权 联通块加权 全图加权 单点询问 联通块询问 ...
- UVA 1455 Kingdom 线段树+并查集
并查集维护:y的最大最小值.城市数量 线段树维护:城市数量,洲数量 合并两个集合时,先在线段树上删除两个子集合的旧的信息,然后再将合并完的新集合更新到线段树. //#pragma comment(li ...
- bzoj 2054: 疯狂的馒头(线段树||并查集)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2054 线段树写法: 点的颜色只取决于最后一次染的颜色,所以我们可以倒着维护,如果当前区间之前 ...
- 【BZOJ5005】乒乓游戏 [线段树][并查集]
乒乓游戏 Time Limit: 10 Sec Memory Limit: 256 MB Description Input Output Sample Input 5 1 1 5 1 5 11 2 ...
- P5631-最小mex生成树【线段树,并查集】
正题 题目链接:https://www.luogu.com.cn/problem/P5631 题目大意 nnn个点mmm条边的一张图,求mexmexmex值最小的一棵生成树. 解题思路 考虑比较暴力的 ...
- 可持久化线段树【主席树】可持久化并查集【主席树+并查集】
笼统的主席树原理 众所周知, 主席树是可以持久化的, 换言之你能知道你所维护信息的所有历史状态. 主席树是这样做的: 1. 首先建一颗朴素的线段树,代表初始状态 (下图黑色) , 也就是第0次操作后的 ...
- hdu 1558(线段相交+并查集)
题意:给你一些操作,P后边输入四个值,分别代表一条线段的起点.终点坐标,当输入Q时,后边输入一个整形值K,输出第k条线段所在的集合中包含的线段的个数. 解题思路:线段相交+并查集,sum[i]表示i所 ...
- HDU 1512 Monkey King 左偏树 + 并查集
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1512 题意:有n个猴子,一开始每个猴子只认识自己.每个猴子有一个力量值,力量值越大表示这个猴子打架越厉害. ...
- 判断线段相交(hdu1558 Segment set 线段相交+并查集)
先说一下题目大意:给定一些线段,这些线段顺序编号,这时候如果两条线段相交,则把他们加入到一个集合中,问给定一个线段序号,求在此集合中有多少条线段. 这个题的难度在于怎么判断线段相交,判断玩相交之后就是 ...
最新文章
- 再见,Eclipse。
- 13-SDEI: Software Delegated Exception Interface
- AndroidStudio中提示:Didn‘t find class “android.support.v7.widget.RecyclerView“
- MaxCompute - ODPS重装上阵 第三弹 - 复杂类型
- 电脑解锁后黑屏有鼠标_电脑开机黑屏只有鼠标如何解决
- Linux命令(1)—— xargs 命令
- [POJ3080 Blue Jeans]
- LINUX 命令手册
- 智能语音翻译APP——腾讯翻译君
- 华为交换机的基本配置命令
- DataTable常用数据筛选方法
- STM32基于HAL工程读取DHT11/DHT22/AM2302/AM2301
- sinr是什么意思_信噪比有负的吗?表示什么意思?
- 重卡自动驾驶进入“正规战”
- js下载文件方法记录
- 大数据——Flink 知识点整理
- [附源码]计算机毕业设计JAVA汽车租赁系统
- 【数学建模】模糊综合评价
- PostgreSQL 14分布式Citus单机多实例部署
- 文盲确定为不能用计算机,最初人们把文盲定义为 “不识字的人”;后来又把文盲确定为“看不懂现代信息符号、图表的人”;而现在联合国把文盲确定为“不能用计算机交流的人”。从哲学上看,这表明...
热门文章
- 007 使用SpringMVC开发restful API五--异常处理
- 微软Azure云计算服务主导全球
- 《读编程珠玑有感》——细节处见技术
- linq里的select和selectmany操作 投影运算
- require.js 的简单运用 --兰
- Git学习(四)标签管理
- mysql root拿shell_mysql的几种获取shell和提权的方式
- nginx linux 部署web项目名,Linux部署web项目配置Nginx
- mysql开启中继日志,MySQL复制应用中继日志解析
- python将对象放入列表根据某个属性排升序_python实现对象列表根据某个属性排序的方法详解...