题目链接:http://codeforces.com/contest/811/problem/E

题意:给定一个行数为10 列数10w的矩阵,每个方块是一个整数, 给定l和r 求范围内的联通块数量 所谓联通块即数字相等

题解:显然可以用线段树来维护一下,一共就10行。线段树唯一难处理的就是push_up不好弄,这一要利用一下并查集,因为求的是连通块

的个数。具体看一下代码的注释。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int M = 1e5 + 10;
struct TnT {
int l , r , sum;
int lsum[11] , rsum[11];
}T[M << 2];
int f[M << 4] , a[11][M];
int n , m , q , tot;
//并查集并的是她们连通块的种类。
void init() {
for(int i = 1 ; i <= n * m ; i++) {
f[i] = i;
}
}
int find(int x) {
if(x == f[x]) return x;
int tmp = find(f[x]);
return f[x] = tmp;
}
TnT push_up(int mid , TnT le , TnT re) {
TnT ans;
ans.sum = le.sum + re.sum;
for(int j = 1 ; j <= n ; j++) {
f[le.lsum[j]] = le.lsum[j];
f[le.rsum[j]] = le.rsum[j];
f[re.lsum[j]] = re.lsum[j];
f[re.rsum[j]] = re.rsum[j];
}//这里一定要这样赋值一下因为合并的时候这两部分肯定不属于同意连通块,所以不能让她们的父亲相同,而且她们的父亲会在合并的时候变成相同的所以这里要每次给她们定一个新父亲。
for(int j = 1 ; j <= n ; j++) {
if(a[j][mid] == a[j][mid + 1]) {
int t1 = find(le.rsum[j]) , t2 = find(re.lsum[j]);
if(t1 != t2) {
ans.sum--;
f[t1] = t2;
}//显然如果不是相同父亲的sum--
}
}
for(int j = 1 ; j <= n ; j++) {
ans.lsum[j] = find(le.lsum[j]);
ans.rsum[j] = find(re.rsum[j]);
}//pushup一下ans的lsum于rsum
ans.l = le.l , ans.r = re.r;
return ans;
}
void build(int i , int l , int r) {
int mid = (l + r) >> 1;
T[i].l = l , T[i].r = r , T[i].sum = 0;
if(l == r) {
for(int j = 1 ; j <= n ; j++) {
if(a[j][l] == a[j - 1][l]) {
T[i].lsum[j] = T[i].rsum[j] = T[i].lsum[j - 1];//如果相邻两个一样那么她们肯定属于一个连通块所以连通块下表一样,
}
else {
T[i].lsum[j] = T[i].rsum[j] = ++tot;
T[i].sum++;
}
}
return ;
}
build(i << 1 , l , mid);
build((i << 1) | 1 , mid + 1 , r);
T[i] = push_up(mid , T[i << 1] , T[(i << 1) | 1]);
}
TnT query(int i , int l , int r) {
int mid = (T[i].l + T[i].r) >> 1;
if(T[i].l == l && T[i].r == r) {
return T[i];
}
T[i] = push_up(mid , T[i << 1] , T[(i << 1) | 1]);
if(mid < l) return query((i << 1) | 1 , l , r);
else if(mid >= r) return query(i << 1 , l , r);
else {
return push_up(mid , query(i << 1 , l , mid) , query((i << 1) | 1 , mid + 1 , r));
}
}
int main() {
scanf("%d%d%d" , &n , &m , &q);
tot = 0;
for(int i = 1 ; i <= n ; i++) {
for(int j = 1 ; j <= m ; j++) {
scanf("%d" , &a[i][j]);
}
}
init();
build(1 , 1 , m);
while(q--) {
int x , y;
scanf("%d%d" , &x , &y);
printf("%d\n" , query(1 , x , y).sum);
}
return 0;
}

codeforces 811 E. Vladik and Entertaining Flags(线段树+并查集)的更多相关文章

  1. 【Codeforces811E】Vladik and Entertaining Flags [线段树][并查集]

    Vladik and Entertaining Flags Time Limit: 20 Sec  Memory Limit: 512 MB Description n * m的矩形,每个格子上有一个 ...

  2. 2022.02.27 CF811E Vladik and Entertaining Flags(线段树+并查集)

    2022.02.27 CF811E Vladik and Entertaining Flags(线段树+并查集) https://www.luogu.com.cn/problem/CF811E Ste ...

  3. [WC2005]双面棋盘(线段树+并查集)

    线段树+并查集维护连通性. 好像 \(700ms\) 的时限把我的常数超级大的做法卡掉了, 必须要开 \(O_2\) 才行. 对于线段树的每一个结点都开左边的并查集,右边的并查集,然后合并. \(Co ...

  4. codeforces 811E Vladik and Entertaining Flags(线段树+并查集)

    codeforces 811E Vladik and Entertaining Flags 题面 \(n*m(1<=n<=10, 1<=m<=1e5)\)的棋盘,每个格子有一个 ...

  5. 【BZOJ-3673&3674】可持久化并查集 可持久化线段树 + 并查集

    3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 1878  Solved: 846[Submit][Status ...

  6. 【XSY2707】snow 线段树 并查集

    题目描述 有\(n\)个人和一条长度为\(t\)的线段,每个人还有一个工作范围(是一个区间).最开始整条线段都是白的.定义每个人的工作长度是这个人的工作范围中白色部分的长度(会随着线段改变而改变).每 ...

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

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

  8. ZOJ 4100 浙江省第16届大学生程序设计竞赛 A题 Vertices in the Pocket 线段树+并查集

    正赛的时候完全没看这个题,事后winterzz告诉我他想出来的解法. 首先题意是给出n个点,m次操作. 操作有一种是连接两个点,另一种是求此时再为这个图连k条边,最少和最多能有几个联通块. 最少的求法 ...

  9. 【CF687D】Dividing Kingdom II 线段树+并查集

    [CF687D]Dividing Kingdom II 题意:给你一张n个点m条边的无向图,边有边权$w_i$.有q个询问,每次给出l r,问你:如果只保留编号在[l,r]中的边,你需要将所有点分成两 ...

随机推荐

  1. SWT 注意事项

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

  2. jenkins未授权访问漏洞

    jenkins未授权访问漏洞 一.漏洞描述 未授权访问管理控制台,可以通过脚本命令行执行系统命令.通过该漏洞,可以后台管理服务,通过脚本命令行功能执行系统命令,如反弹shell,wget写webshe ...

  3. js中数组和对象的合并

    1 数组合并 1.1 concat 方法 1 2 3 4 var a=[1,2,3],b=[4,5,6]; var c=a.concat(b); console.log(c);// 1,2,3,4,5 ...

  4. 自定义ItemToggleView

    极力推荐文章:欢迎收藏 Android 干货分享 阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android 本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以 ...

  5. java常见面试题目(一)

    在大四实习阶段,秋招的时候,面试了很多家公司,总结常见的java面试题目:(答案可以自己百度) 1.你所用oracle的版本号是多少? 2.tomcat修改8080端口号的配置文件是哪个? 3.myb ...

  6. Netty学习(六)-LengthFieldBasedFrameDecoder解码器

    在TCP协议中我们知道当我们在接收消息时候,我们如何判断我们一次读取到的包就是整包消息呢,特别是对于使用了长连接和使用了非阻塞I/O的程序.上节我们也说了上层应用协议为了对消息进行区分一般采用4种方式 ...

  7. eclipse Maven配置以及使用方法

    简述: 现需要在Eclipse中配置Maven插件,同时安装maven应用,配置Maven环境变量,建立Maven管理的工程,并用Maven导入Gson包, 编写简易Json输出程序 步骤: 1. 首 ...

  8. android——Fragment

    谷歌官方文档的介绍: https://developer.android.com/guide/components/fragments.html#Design Fragment 表示 Activity ...

  9. ggplot2 |legend参数设置,图形精雕细琢

    本文首发于微信公众号“生信补给站”,https://mp.weixin.qq.com/s/A5nqo6qnlt_5kF3_GIrjIA 学习了ggplot2|详解八大基本绘图要素后,就可以根据自己的需 ...

  10. jdk_Windows基础环境配置

    JAVA环境配置 windows 系统环境变量配置: JAVA_HOME C:\Java\jdk1.8.0_25 Path %JAVA_HOME%\bin; classpath .;%JAVA_HOM ...