P7295-[USACO21JAN]Paint by Letters P【平面图欧拉公式】

正题

题目链接:https://www.luogu.com.cn/problem/P7295


题目大意

给出n∗mn*mnm的网格,每个格子上有字母,相同字母的四联通相邻格子为连通,每次询问一个子矩阵求连通块个数。

1≤n,m,q≤10001\leq n,m,q\leq 10001n,m,q1000


解题思路

首先一张连通的平面图有欧拉公式
V+F=E+2V+F=E+2V+F=E+2
其中V,E,FV,E,FV,E,F分别表示点数,边数,区域个数(对偶图点数)。

然后不连通的对偶图会共用一个无界域,设为CCC个连通块,无界域会重复统计C−1C-1C1次,然后联立得
V+F−E=C+1V+F-E=C+1V+FE=C+1
然后考虑怎么用这个求,首先是V,EV,EV,E,这个很容易搞,VVV直接计算,EEE用二维前缀和算就好了。

主要是FFF怎么搞,先构出不严格的对偶图(就是每个格子边上的点当做点),然后FFF就是对偶图的连通块数。

对于整张图的每个连通块,我们选择任意一个点标记,然后记录每个点对应连通块的标记点,然后直接二维前缀和统计连通块内的标记点个数,然后枚举边界减去边上不完整被统计的的连通块最后加上无界域就好了。

时间复杂度O(nm+q(n+m))O(nm+q(n+m))O(nm+q(n+m))


code

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1100;
const int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
int n,m,q,E[2][N][N],mx[N][N],my[N][N],F[N][N];
char s[N][N];bool v[N][N];
bool edg(int x,int y,int zx,int zy){if(zx<0||zy<0||zx>n||zy>m)return 0;if(zx>0&&zx<n&&zy==y+1)return (s[x][y+1]!=s[x+1][y+1]);if(zx>0&&zx<n&&zy==y-1)return (s[x][y]!=s[x+1][y]);if(zy>0&&zy<m&&zx==x+1)return (s[x+1][y]!=s[x+1][y+1]);if(zy>0&&zy<m&&zx==x-1)return (s[x][y]!=s[x][y+1]);return 1;
}
void dfs(int x,int y){if(x==1&&y==4)x++,x--;if(v[x][y])return;v[x][y]=1;for(int k=0;k<4;k++){int zx=x+dx[k],zy=y+dy[k];if(edg(x,y,zx,zy)){mx[zx][zy]=mx[x][y];my[zx][zy]=my[x][y];dfs(zx,zy);}}return;
}
#define Get(F,x1,y1,x2,y2) (F[x2][y2]-((x1)?F[x1-1][y2]:0)-((y1)?F[x2][y1-1]:0)+(((x1)&&(y1))?F[x1-1][y1-1]:0))
int check(int x,int y,int x1,int y1,int x2,int y2){if(!v[x][y]&&x>=x1&&x<=x2&&y>=y1&&y<=y2){v[x][y]=1;return 1;}return 0;
}
int main()
{scanf("%d%d%d",&n,&m,&q);for(int i=1;i<=n;i++)scanf("%s",s[i]+1);for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){E[0][i][j]=E[0][i-1][j]+E[0][i][j-1]-E[0][i-1][j-1];E[1][i][j]=E[1][i-1][j]+E[1][i][j-1]-E[1][i-1][j-1];if(s[i][j]==s[i][j+1])E[0][i][j]++;if(s[i][j]==s[i+1][j])E[1][i][j]++;}for(int i=0;i<=n;i++)for(int j=0;j<=m;j++)if(!v[i][j]){mx[i][j]=i;my[i][j]=j;F[i][j]++;dfs(i,j);}for(int i=0;i<=n;i++)for(int j=0;j<=m;j++)F[i][j]+=(i?F[i-1][j]:0)+(j?F[i][j-1]:0)-((i&&j)?F[i-1][j-1]:0);memset(v,0,sizeof(v));while(q--){int x1,y1,x2,y2,ans=0;scanf("%d%d%d%d",&x1,&y1,&x2,&y2);ans+=(x2-x1+1)*(y2-y1+1);if(y1!=y2)ans-=Get(E[0],x1,y1,x2,y2-1);if(x1!=x2)ans-=Get(E[1],x1,y1,x2-1,y2);x1--;y1--;ans+=Get(F,x1,y1,x2,y2);for(int i=x1;i<=x2;i++){ans-=check(mx[i][y1],my[i][y1],x1,y1,x2,y2);ans-=check(mx[i][y2],my[i][y2],x1,y1,x2,y2);}for(int i=y1;i<=y2;i++){ans-=check(mx[x1][i],my[x1][i],x1,y1,x2,y2);ans-=check(mx[x2][i],my[x2][i],x1,y1,x2,y2);}printf("%d\n",ans);for(int i=x1;i<=x2;i++){v[mx[i][y1]][my[i][y1]]=0;v[mx[i][y2]][my[i][y2]]=0;}for(int i=y1;i<=y2;i++){v[mx[x1][i]][my[x1][i]]=0;v[mx[x2][i]][my[x2][i]]=0;}}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318465.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【活动(深圳)】告别2018之12.22 大湾区.NET Meet 大会 ,同时有网络直播

今年的 Connect(); 主题更加聚焦开发者工具生产力、开源&#xff0c;以及无服务器&#xff08;Serverless&#xff09;云服务。Visual Studio 2019 AI 智能加持的 IntelliCode、实时代码协作共享 Live Share&#xff0c;.NET Core 3.0的预览版本附带了大量更新&#xff0c;旨在…

带花树算法

对于一般的二分图匹配我们肯定会想到匈牙利算法&#xff0c;但是如果图中出现奇环怎么办&#xff1f;此时匈牙利算法就不可以了&#xff0c;就需要另一个算法&#xff1a;带花树算法 主要就是为了解决奇环的问题 我们匹配时会发现&#xff0c;如果存在奇环&#xff0c;传统的匈…

最短路径(状压dp)(ybtoj)

解析 “bug总有de完的一天” 头疼 暴力写的话本题显然复杂度是假的 有一个很好的思路优化时间复杂度 先用dp[k][i]表示**从第k个关键点到任意i点的最短路 跑k遍 SPFA或迪杰斯特拉 即可 然后转移时可以只考虑关键点 使状态转移数大大降低 细节 头真疼 边界条件&#xff1a; …

P3352-[ZJOI2016]线段树【dp】

正题 题目链接:https://www.luogu.com.cn/problem/P3352 题目大意 nnn个数字的一个序列&#xff0c;每次随机选择一个区间让这个区间所有数等于这个区间的最大值&#xff0c;重复qqq次&#xff0c;对每个位置求所有情况下这个位置的值的和。 1≤n,q≤4001\leq n,q\leq 4001≤n…

P2403 [SDOI2010]所驼门王的宝藏(强连通分量)(拓扑排序)

文章目录题目描述解析代码洛谷传送门题目描述 解析 看题目要求很容易想到强连通分量缩点加拓扑dp 但是问题在于存图 第一感就是和暴力和每个点连边 但那样无论点数和边数都很爆炸 随后我们发现这个图非常稀疏 所以我们可以只连有宝藏的点 然而这样边数会被一行横门这样的数据…

Xamarin.Forms之UserDialogs 重制版本

在 forms 里面&#xff0c;目前使用比较多的弹出组件是 Acr.UserDialogs &#xff0c;但是这个组件有些小问题&#xff0c;比如 loading .hide 会同时把 toast 给一起关掉&#xff0c;android 下的 toast 希望是 安卓原生的toast 样子&#xff0c;而不是 底部弹出一个横条&…

H.Minimum-cost Flow

H.Minimum-cost Flow 题目&#xff1a; 其实就是给出每条边的单位费用&#xff0c;q次查询&#xff0c;每次查询改变所有边的容量&#xff08;所有边容量一样&#xff09;&#xff0c;问最后流出1流量的最小花费是多少&#xff1f; 题解&#xff1a; 暴力做法肯定是每次询问…

P6177-Count on a tree II/[模板]树分块

正题 题目链接:https://www.luogu.com.cn/problem/P6177 题目大意 nnn个点的一棵树mmm次询问树上颜色。 强制在线 1≤n≤4105,1≤m≤105,0≤vali<2311\leq n\leq 4\times 10^5,1\leq m\leq 10^5,0\leq val_i<2^{31}1≤n≤4105,1≤m≤105,0≤vali​<231 解题思路 把所…

eShopOnContainers 看微服务③:Identity Service

引言通常&#xff0c;服务所公开的资源和 API 必须仅限受信任的特定用户和客户端访问。那进行 API 级别信任决策的第一步就是身份认证——确定用户身份是否可靠。在微服务场景中&#xff0c;身份认证通常统一处理。一般有两种实现形式&#xff1a;基于API 网关中心化认证&#…

P2168 [NOI2015] 荷马史诗(哈夫曼编码树)

传送门 文章目录题目描述解析细节代码题目描述 解析 其实就是构造一棵树 另所有带权点都为叶子节点 其代价为权值与深度的乘积 求最小代价及最小代价下的最小深度 可以看成一开始有n棵小树 每次把k棵合并在一起 最后合成一棵大树就行了 每次合并的代价是k棵树的权值和 看到这…

B-Suffix Array

B-Suffix Array 题意&#xff1a; 一个字符串只含有a和b&#xff0c;先给出b数组的构造方式&#xff1a; 对于每个位置i来说&#xff1a; 如果存在一个位置j&#xff0c;使得j<i,且s[j] s[i],则b[i]i-j否则b[i]0 现在对字符串每个后缀都构造B数组&#xff0c;并按照字典…

Wannafly挑战赛10F-小H和遗迹【Trie,树状数组】

正题 题目链接:https://ac.nowcoder.com/acm/contest/72/F 题目大意 nnn个字符串&#xff0c;包括小写字母和#\##。其中#\##可以替换为任意字符串。求有多少对字符串可能相同。 保证每个字符串至少有一个#\##。 2≤n≤500000,∑i1n∣si∣≤1062\leq n\leq 500000,\sum_{i1}^n…

线段树合并、分裂

基本概念&#xff1a; 如果需要维护许多个大小为 \(10^5\) 级别的多重集&#xff0c;可以看做给每一个多重集建立一棵线段树。线段树的合并、分裂就是多重集的累加、分开。 这里使用动态开点的方式存储线段树树。 如果一个节点为空&#xff0c;那么它的编号为 \(0\) 。 变量释义…

(神奇的)虚树(初步了解)

参考文献&#xff1a; 博文1 博文2 博文3 引入 在一类树上动态规划问题中,题目给出的询问往往包含树上的很多各节点,并保证总的点数规模小于某个值. 如果我们直接在整颗树上进行dp的话,时间复杂度与询问的次数有关,这显然是不可接受的,如果我们可以找到一种动态规划的方法,使…

P2048 [NOI2010] 超级钢琴(RMQ 贪心)

文章目录题目描述解析代码传送门题目描述 解析 首先&#xff0c;如果只有一个和弦&#xff0c;那么问题显然简单了 用前缀和结合ST表随便做做即可 然而 这次要求前k大的 怎么办呢&#xff1f; 参照之前有一道序列合并的做法 我们想到&#xff0c;可以先建一个优先队列&#xf…

微服务架构基础之Service Mesh

ServiceMesh(服务网格) 概念在社区里头非常火&#xff0c;有人提出 2018 年是 ServiceMesh 年&#xff0c;还有人提出 ServiceMesh 是下一代的微服务架构基础。那么到底什么是 ServiceMesh&#xff1f;它的诞生是为了解决什么问题&#xff1f;企业是否适合引入 ServiceMesh&…

[SDOI2011]消耗战

[SDOI2011]消耗战 题意&#xff1a; 给出n个点的一棵带有边权的树,以及q个询问.每次询问给出k个点,询问这使得这k个点与1点不连通所需切断的边的边权和最小是多少. 题解&#xff1a; 树型dp虚树 dp[x]:切断x及其子树上询问点的最小代价 预处理出minv[pos]代表从11到pos路径…

【做题记录】CF1428E Carrots for Rabbits—堆的妙用

CF1428E Carrots for Rabbits 题意&#xff1a; 有 \(n\) 个萝卜&#xff0c;每个萝卜的初始大小为 \(a_i\) 。现在要把这些萝卜切为为 \(k\) 个。吃每一个萝卜的时间为这个萝卜的大小的平方&#xff0c;求吃完所有萝卜的最小时间&#xff0c;即 \(\sum_{i1}^{k}{a_i^2}\) 最小…

P4716-[模板]最小树形图

正题 题目链接:https://www.luogu.com.cn/problem/P4716 题目大意 给出nnn个点mmm条边的一张有向图&#xff0c;求以rrr为根的最小外向树。 1≤n≤100,1≤m≤1041\leq n\leq 100,1\leq m\leq 10^41≤n≤100,1≤m≤104 解题思路 考虑一种贪心&#xff0c;对于每个点我们先选出…

P1081 [NOIP2012 提高组] 开车旅行(倍增)(动态规划)

洛谷传送门 文章目录题目描述解析代码题目描述 解析 利用倍增&#xff0c;设计dp慢慢敲即可。。。 注意距离累加在一起会爆int&#xff0c;需要ll 特判条件非常之复杂。。。 心力交瘁&#xff0c;就酱了 代码 #include <bits/stdc.h> using namespace std; #define ll…