2022.02.27 CF811E Vladik and Entertaining Flags
2022.02.27 CF811E Vladik and Entertaining Flags
https://www.luogu.com.cn/problem/CF811E
Step 1 题意
在一个 n*m 的网格上每个格子都有颜色,q 次询问,每次询问只保留 l 至 r 列时有多少个四连通的颜色块。两个格子同色但不连通算在不同的颜色块内。
Step 2 分析
这道题我首先大力找到一个错误规律,这个暂且不说,直接上正解。
对于每一列的格子搞线段树,记录每列有几个连通块,每列的最左侧和最右侧的节点属于哪个连通块。
合并的时候合并两个连通块相邻的两列,如果颜色一致并且fa不一样,总连通块的数量减一。不过需要初始化一下相邻两列格子的并查集。
Step 3 代码如下
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,m,q,mapi[15][N],fa[N*15];
int tot;
struct node{
int x,y,L[15],R[15],sum;
}t[N<<4];
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0'){
s=s*10+ch-'0';
ch=getchar();
}
return s*w;
}
inline int find(int x){
return x==fa[x]?x:fa[x]=find(fa[x]);
}
inline node update(node x,node y,int l,int r){
node ans;
ans.sum=x.sum+y.sum;
for(int i=1;i<=n;i++)
fa[x.L[i]]=x.L[i],fa[x.R[i]]=x.R[i],
fa[y.L[i]]=y.L[i],fa[y.R[i]]=y.R[i];
for(int i=1;i<=n;i++)ans.L[i]=x.L[i],ans.R[i]=y.R[i];
for(int i=1;i<=n;i++)
if(mapi[i][l]==mapi[i][r]){
int xi=find(fa[x.R[i]]);
int yi=find(fa[y.L[i]]);
if(xi!=yi)fa[xi]=yi,--ans.sum;
}
for(int i=1;i<=n;i++)
ans.L[i]=find(ans.L[i]),ans.R[i]=find(ans.R[i]);
return ans;
}
inline void build(int x,int l,int r){
if(l==r){
for(int i=1;i<=n;i++)
if(mapi[i][l]==mapi[i-1][l])
t[x].L[i]=t[x].R[i]=t[x].L[i-1];
else t[x].L[i]=t[x].R[i]=++tot,++t[x].sum;
return ;
}
int mid=(l+r)>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
t[x]=update(t[x<<1],t[x<<1|1],mid,mid+1);
}
inline node query(int x,int l,int r,int L,int R){
if(l>=L&&r<=R)return t[x];
int mid=(l+r)>>1;
int flaga=0,flagb=0;
node a,b,ans;
if(L<=mid)a=query(x<<1,l,mid,L,R),flaga=1;
if(R>mid)b=query(x<<1|1,mid+1,r,L,R),flagb=1;
if(flaga&&!flagb)ans=a;
else if(flagb&&!flaga)ans=b;
else if(flaga&&flagb)ans=update(a,b,mid,mid+1);
return ans;
}
signed main(){
n=read();m=read();q=read();
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)mapi[i][j]=read();
//cout<<"Case 1 "<<endl;
build(1,1,m);
//cout<<"Case 2 "<<endl;
for(int i=1;i<=q;i++){
int u,v;
u=read();v=read();
node fin=query(1,1,m,u,v);
cout<<fin.sum<<endl;
}
return 0;
}
2022.02.27 CF811E Vladik and Entertaining Flags的更多相关文章
- 2022.02.27 CF811E Vladik and Entertaining Flags(线段树+并查集)
2022.02.27 CF811E Vladik and Entertaining Flags(线段树+并查集) https://www.luogu.com.cn/problem/CF811E Ste ...
- CF811E Vladik and Entertaining Flags
嘟嘟嘟 看题目这个架势,就知道要线段树,又看到维护联通块,那就得并查集. 所以,线段树维护并查集. 然而如果没想明白具体怎么写,就会gg的很惨-- 首先都容易想到维护区间联通块个数和区间端点两列的点, ...
- codeforces 811E Vladik and Entertaining Flags(线段树+并查集)
codeforces 811E Vladik and Entertaining Flags 题面 \(n*m(1<=n<=10, 1<=m<=1e5)\)的棋盘,每个格子有一个 ...
- 【Codeforces811E】Vladik and Entertaining Flags [线段树][并查集]
Vladik and Entertaining Flags Time Limit: 20 Sec Memory Limit: 512 MB Description n * m的矩形,每个格子上有一个 ...
- Vladik and Entertaining Flags
Vladik and Entertaining Flags time limit per test 2 seconds memory limit per test 256 megabytes inpu ...
- Vladik and Entertaining Flags CodeForces - 811E (并查集,线段树)
用线段树维护每一块左右两侧的并查集, 同色合并时若不连通则连通块数-1, 否则不变 #include <iostream> #include <algorithm> #incl ...
- codeforces 811 E. Vladik and Entertaining Flags(线段树+并查集)
题目链接:http://codeforces.com/contest/811/problem/E 题意:给定一个行数为10 列数10w的矩阵,每个方块是一个整数, 给定l和r 求范围内的联通块数量 所 ...
- ROS的安装-> rosdep init /update报错2022.02.24实测有效
ROS的安装-> rosdep init /update报错2022.02.24实测有效 一. 解决rosdep_init问题 正常执行sudo rosdep init会报错,如下: ERR ...
- 2022.02.21 UB
2022.02.21 UB 参考资料: https://zhuanlan.zhihu.com/p/141467895 https://blog.csdn.net/ghscarecrow/article ...
随机推荐
- Mybatis的xml配置(mybatis-config.xml)精简笔记
老规矩,看着官方文档学 首先,我们需要知道的是,在MyBatis 的xml配置文件中,这些影响 MyBatis 行为的属性之间的设置是有先后顺序的.配置的先后顺序依照properties, setti ...
- -std=c++11 编译器设置
range-based 'for' loops are not allowed in C++98 mode
- jvm大局观之内存管理篇(二):当java中new一个对象,背后发生了什么
https://zhuanlan.zhihu.com/p/257863129?utm_source=ZHShareTargetIDMore 番茄番茄我是西瓜 那是我日夜思念深深爱着的人啊~ 已关注 ...
- mysql join 底层原理
你知道 Sql 中 left join 的底层原理吗? 2019-09-10阅读 7130 https://cloud.tencent.com/developer/column/2367 01.前 ...
- 深入理解Java虚拟机-JVM运行时数据区域
一.运行时数据区域 1.程序计数器 程序计数器( Program Counter Register) 是一块较小的内存空间, 它可以看作是当前线程所执行的字节码的行号指示器. Java虚拟机的多线程是 ...
- Hashmap如何同步?
当我们需要一个同步的HashMap时,有两种选择: ●使用Collections.synchronizedMap(..)来同步HashMap. ●使用ConcurrentHashMap的 这两个选项之 ...
- 什么是 Apache Kafka?
Apache Kafka 是一个分布式发布 - 订阅消息系统.它是一个可扩展的,容错的 发布 - 订阅消息系统,它使我们能够构建分布式应用程序.这是一个 Apache 顶 级项目.Kafka 适合离线 ...
- Elasticsearch 对于大数据量(上亿量级)的聚合如何实现?
Elasticsearch 提供的首个近似聚合是 cardinality 度量.它提供一个字段的基数, 即该字段的 distinct 或者 unique 值的数目.它是基于 HLL 算法的.HLL 会 ...
- String s = new String(“xyz”);创建了几个字符串对象?
两个对象,一个是静态区的"xyz",一个是用 new 创建在堆上的对象.
- 动态规划 洛谷P1048 [NOIP2005 普及组] 采药
洛谷P1048 [NOIP2005 普及组] 采药 洛谷的一个谱架-的题目,考的是01背包问题,接下来分享一下我的题解代码. AC通过图: 我的代码: 1 //动态规划 洛谷P1048 [NOIP20 ...