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

  4 5 4
  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

  6
  7
  3
  4

HINT

1 ≤ n ≤ 10, 1 ≤ m, q ≤ 1e5, 1 ≤ l ≤ r ≤ m

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 [线段树][并查集]相关推荐

  1. P3273-[SCOI2011]棘手的操作【线段树,并查集】

    正题 题目链接:https://www.luogu.com.cn/problem/P3273 题目大意 nnn个点有权值,要求支持操作 连接两个点 单点加权 联通块加权 全图加权 单点询问 联通块询问 ...

  2. UVA 1455 Kingdom 线段树+并查集

    并查集维护:y的最大最小值.城市数量 线段树维护:城市数量,洲数量 合并两个集合时,先在线段树上删除两个子集合的旧的信息,然后再将合并完的新集合更新到线段树. //#pragma comment(li ...

  3. bzoj 2054: 疯狂的馒头(线段树||并查集)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2054 线段树写法: 点的颜色只取决于最后一次染的颜色,所以我们可以倒着维护,如果当前区间之前 ...

  4. 【BZOJ5005】乒乓游戏 [线段树][并查集]

    乒乓游戏 Time Limit: 10 Sec  Memory Limit: 256 MB Description Input Output Sample Input 5 1 1 5 1 5 11 2 ...

  5. P5631-最小mex生成树【线段树,并查集】

    正题 题目链接:https://www.luogu.com.cn/problem/P5631 题目大意 nnn个点mmm条边的一张图,求mexmexmex值最小的一棵生成树. 解题思路 考虑比较暴力的 ...

  6. 可持久化线段树【主席树】可持久化并查集【主席树+并查集】

    笼统的主席树原理 众所周知, 主席树是可以持久化的, 换言之你能知道你所维护信息的所有历史状态. 主席树是这样做的: 1. 首先建一颗朴素的线段树,代表初始状态 (下图黑色) , 也就是第0次操作后的 ...

  7. hdu 1558(线段相交+并查集)

    题意:给你一些操作,P后边输入四个值,分别代表一条线段的起点.终点坐标,当输入Q时,后边输入一个整形值K,输出第k条线段所在的集合中包含的线段的个数. 解题思路:线段相交+并查集,sum[i]表示i所 ...

  8. HDU 1512 Monkey King 左偏树 + 并查集

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1512 题意:有n个猴子,一开始每个猴子只认识自己.每个猴子有一个力量值,力量值越大表示这个猴子打架越厉害. ...

  9. 判断线段相交(hdu1558 Segment set 线段相交+并查集)

    先说一下题目大意:给定一些线段,这些线段顺序编号,这时候如果两条线段相交,则把他们加入到一个集合中,问给定一个线段序号,求在此集合中有多少条线段. 这个题的难度在于怎么判断线段相交,判断玩相交之后就是 ...

最新文章

  1. 再见,Eclipse。
  2. 13-SDEI: Software Delegated Exception Interface
  3. AndroidStudio中提示:Didn‘t find class “android.support.v7.widget.RecyclerView“
  4. MaxCompute - ODPS重装上阵 第三弹 - 复杂类型
  5. 电脑解锁后黑屏有鼠标_电脑开机黑屏只有鼠标如何解决
  6. Linux命令(1)—— xargs 命令
  7. [POJ3080 Blue Jeans]
  8. LINUX 命令手册
  9. 智能语音翻译APP——腾讯翻译君
  10. 华为交换机的基本配置命令
  11. DataTable常用数据筛选方法
  12. STM32基于HAL工程读取DHT11/DHT22/AM2302/AM2301
  13. sinr是什么意思_信噪比有负的吗?表示什么意思?
  14. 重卡自动驾驶进入“正规战”
  15. js下载文件方法记录
  16. 大数据——Flink 知识点整理
  17. [附源码]计算机毕业设计JAVA汽车租赁系统
  18. 【数学建模】模糊综合评价
  19. PostgreSQL 14分布式Citus单机多实例部署
  20. 文盲确定为不能用计算机,最初人们把文盲定义为 “不识字的人”;后来又把文盲确定为“看不懂现代信息符号、图表的人”;而现在联合国把文盲确定为“不能用计算机交流的人”。从哲学上看,这表明...

热门文章

  1. 007 使用SpringMVC开发restful API五--异常处理
  2. 微软Azure云计算服务主导全球
  3. 《读编程珠玑有感》——细节处见技术
  4. linq里的select和selectmany操作 投影运算
  5. require.js 的简单运用 --兰
  6. Git学习(四)标签管理
  7. mysql root拿shell_mysql的几种获取shell和提权的方式
  8. nginx linux 部署web项目名,Linux部署web项目配置Nginx
  9. mysql开启中继日志,MySQL复制应用中继日志解析
  10. python将对象放入列表根据某个属性排升序_python实现对象列表根据某个属性排序的方法详解...