【bzoj 1414】对称的正方形 单调队列+manacher
Description
Input
Output
Sample Input
4 2 4 4 4
3 1 4 4 3
3 5 3 3 3
3 1 5 3 3
4 2 1 2 4
Sample Output
数据范围
对于30%的数据 n,m≤100
对于100%的数据 n,m≤1000 ,矩阵中的数的大小≤109
题解:
蒟蒻写了4h……(本来是想怂,但看到人家说gang了一晚上,然后默默关了网页自己去作了),还有,膜bzoj 1414榜上900B+400MS大佬。
首先用manacher,双倍复制原数组,跑出$P_{0,i,j},P_{1,i,j}$,分别表示第i行j列的横着的和竖着的回文半径。
显然只要求出每个位置的最大正方形边长答案就出来了。
我们以每个位置$(i,j)$为坐标轴原点,显然,我们只要得到x,y轴上的回文半径即可。先讨论x非负轴。同时,对于每个位置我们可以观察发现,在x轴上的位置,应该满足其$x-p[1][i][x]+1<=j$。然后发现对于$(i,j+1)$是可以继承满足$(i,j)$的一部分点,而不能继承的只有$(i,j)$在x轴对应点,同时我们可能会有一部分新点加入$(i,j+1)$的集合点。(⊙v⊙)嗯,这不就是队列的时间关系嘛。
然后怎么选取$(i,j)$所能得到的此时尽可能最大值边长呢。我们可以画个图,观察发现,我们在$(i,j)$点集的选取,只和最小值有关,所以当出现第一个不满足$x-p_{1,i,x}+1<=j$的点就没必要再在非负半轴上往后扫了。
证明的话倒是挺简单的,就不多说了。
以上一结合就得到了我们需要的数据结构,单调队列。
那么对于x非正半轴以及y轴的情况也与x非负半轴的情况相同。时间复杂度$O(n^{2})$
最后答案累加每个$(i,j)$奇偶性相同的位置即可。
Ps:可能是我打得蠢……都跑不过带$log$的……
代码:
- #include<cstdio>
- #include<iostream>
- #include<cstring>
- using namespace std;
- inline int read(){
- int s=;char ch=getchar();
- while(ch<''||ch>'') ch=getchar();
- while(ch>=''&&ch<='') s=s*+(ch^),ch=getchar();
- return s;
- }
- int n,m;
- int Mar[][];
- int p[][][];
- inline void manacher(){
- for(int i=;i<=*n+;i++){
- int pos,mar=;
- for(int j=;j<=*m+;j++){
- if(mar>j) p[][i][j]=min(p[][i][pos*-j],mar-j-);
- else p[][i][j]=;
- while(Mar[i][j-p[][i][j]]==Mar[i][j+p[][i][j]]) p[][i][j]++;
- if(mar<j+p[][i][j]-)
- mar=j+p[][i][j]-,pos=j;
- }
- }
- for(int i=;i<=*m+;i++){
- int pos,mar=;
- for(int j=;j<=*n+;j++){
- if(mar>j) p[][i][j]=min(p[][i][pos*-j],mar-j-);
- else p[][i][j]=;
- while(Mar[j-p[][i][j]][i]==Mar[j+p[][i][j]][i]) p[][i][j]++;
- if(mar<j+p[][i][j]-)
- mar=j+p[][i][j]-,pos=j;
- }
- }
- }
- int que[],l,r;
- int re[][];
- int main(){
- n=read(),m=read();
- for(int i=;i<=n;i++)
- for(int j=;j<=m;j++)
- Mar[i<<][j<<]=read();
- for(int i=;i<=*n+;i++)
- Mar[i][]=-,Mar[i][m+<<]=-;
- for(int i=;i<=*m+;i++)
- Mar[][i]=-,Mar[n+<<][i]=-;
- manacher();
- for(int i=;i<=*n;i++){
- l=,r=;
- for(int j=((i^)&)+,k=;j<=*m+;j+=){
- while(k<=*m+&&k-p[][k][i]+<=j){
- while(l<=r&&p[][que[r]][i]>=p[][k][i])
- r--;
- que[++r]=k;
- k++;
- }
- while(l<=r&&que[l]<j)
- l++;
- re[i][j]=min(que[r]-j+,p[][que[l]][i]);
- }
- l=,r=;
- for(int j=*m+-((i^)&),k=*m+;j>=;j-=){
- while(k&&k+p[][k][i]->=j){
- while(l<=r&&p[][que[r]][i]>=p[][k][i])
- r--;
- que[++r]=k--;
- }
- while(l<=r&&que[l]>j)
- l++;
- re[i][j]=min(min(j-que[r]+,p[][que[l]][i]),re[i][j]);
- }
- }
- for(int i=;i<=*m;i++){
- l=,r=;
- for(int j=+((i^)&),k=;j<=*n+;j+=){
- while(k<=*n+&&k-p[][k][i]+<=j){
- while(l<=r&&p[][que[r]][i]>=p[][k][i])
- r--;
- que[++r]=k;
- k++;
- }
- while(l<=r&&que[l]<j)
- l++;
- re[j][i]=min(min(que[r]-j+,p[][que[l]][i]),re[j][i]);
- }
- l=,r=;
- for(int j=*n+-((i^)&),k=*n+;j;j--){
- while(k&&k+p[][k][i]->=j){
- while(l<=r&&p[][que[r]][i]>=p[][k][i])
- r--;
- que[++r]=k--;
- }
- while(l<=r&&que[l]>j)
- l++;
- re[j][i]=min(min(j-que[r]+,p[][que[l]][i]),re[j][i]);
- }
- }
- int ans=;
- for(int i=;i<=*n;i++){
- for(int j=((i^)&)+;j<=*m+;j+=)
- if((i&)==(j&))
- ans+=re[i][j]>>;
- }
- printf("%d",ans);
- }
【bzoj 1414】对称的正方形 单调队列+manacher的更多相关文章
- BZOJ 1047 理想的正方形(单调队列)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1047 题意:给出一个n*m的矩阵.在所有K*K的子矩阵中,最大最小差值最小的是多少? 思 ...
- bzoj 1047 : [HAOI2007]理想的正方形 单调队列dp
题目链接 1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2369 Solved: 1266[Submi ...
- BZOJ 1047: [HAOI2007]理想的正方形( 单调队列 )
单调队列..先对每一行扫一次维护以每个点(x, y)为结尾的长度为n的最大最小值.然后再对每一列扫一次, 在之前的基础上维护(x, y)为结尾的长度为n的最大最小值. 时间复杂度O(ab) (话说还是 ...
- BZOJ 1047: [HAOI2007]理想的正方形 单调队列瞎搞
题意很简明吧? 枚举的矩形下边界和右端点即右下角,来确定矩形位置: 每一个纵列开一个单调队列,记录从 i-n+1 行到 i 行每列的最大值和最小值,矩形下边界向下推移的时候维护一下: 然后在记录的每一 ...
- BZOJ1047: [HAOI2007]理想的正方形 [单调队列]
1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2857 Solved: 1560[Submit][St ...
- BZOJ 1499 [NOI2005] 瑰丽华尔兹 | 单调队列优化DP
BZOJ 1499 瑰丽华尔兹 | 单调队列优化DP 题意 有一块\(n \times m\)的矩形地面,上面有一些障碍(用'#'表示),其余的是空地(用'.'表示).每时每刻,地面都会向某个方向倾斜 ...
- P2216 [HAOI2007]理想的正方形 (单调队列)
题目链接:P2216 [HAOI2007]理想的正方形 题目描述 有一个 \(a\times b\)的整数组成的矩阵,现请你从中找出一个 \(n\times n\)的正方形区域,使得该区域所有数中的最 ...
- bzoj 3831 Little Bird (单调队列优化dp)
/*先贴个n*n的*/ #include<iostream> #include<cstdio> #include<cstring> #define maxn 100 ...
- BZOJ 1499 NOI2005 瑰丽华尔兹 单调队列
题目大意:给定一个m*n的地图,一些点有障碍物,钢琴初始在一个点,每一个时间段能够选择向给定的方向移动一段距离,求最长路径长 朴素DP的话,我们有T个时间段,每一个时间段有m*n个点,n个时间,一定会 ...
随机推荐
- Error filterStart的问题
今天出现这个问题 严重: Error filterStart org.apache.catalina.core.StandardContext start 严重: Context startup fa ...
- python字符串27种常见的方法
如有字符串 mystr = 'hello world itcast and itcastcpp' ,以下是常见的操作: <1>find 检测 str 是否包含在 mystr中,如果是返回开 ...
- 【深入理解Java内存模型】
深入理解Java内存模型(一)--基础 深入理解Java内存模型(二)--重排序 深入理解Java内存模型(三)--顺序一致性 深入理解Java内存模型(四)--volatile 深入理解Java内存 ...
- 对于程序员在boss直聘求职的建议
最近为一个岗位的招聘,在直聘伤刷了三百份简历 0.上传简历最好是PDF,word简历在不同的系统和软件下排版可能会出问题. 1.新职位投得要快,后面投的,有可能看不到. 为了投的命中率,投之前最好看一 ...
- Python自学编程开发路线图(文中有免费资源)
Python核心编程 免费视频资源<Python入门教程>:http://yun.itheima.com/course/145.html Python 基础学习大纲 所处阶段 主讲内容 技 ...
- 转载《分布式任务调度平台XXL-JOB》
<分布式任务调度平台XXL-JOB> 博文转自 https://www.cnblogs.com/xuxueli/p/5021979.html 一.简介 1.1 概述 XXL-J ...
- 集成支付宝,报警告warning: (arm64) /Users/tommy/Desktop/Project/ios-msdk-git/AlipaySDK4Standard/AlipaySDK/Library/UTDI
集成支付宝的时候遇到的问题,找到了解决办法,还说明了原因,非常好,觉得应该记下来,反正以我的记性下次一定是会忘光光哒~ 1) Go to Build Settings -> Build Opt ...
- 读《图解HTTP》有感-(返回结果的HTTP状态码)
写在前面 HTTP状态码是由服务端产生,用于告诉客户端,服务端处理结果的编码 正文 1.状态码的作用是什么?具有什么特征? 状态码的作用是当客户端向服务器发送请求时,描述服务器的响应结果(如:服务器正 ...
- Version 1.6.0 of the JVM is not suitable for the this product.Version:1.8 or greater is required
这个问题时在打开eclipse时报的一个错误,报这个问题的意思我们都明白,说的就是当前版本的jdk版本太低,eclipse需要更高版本的jdk. 那就下一个更高版本的jdk就可以啦,这里我要说说我当时 ...
- css3 resize属性
http://www.w3school.com.cn/cssref/pr_resize.asp 实例 规定可以由用户调整 div 元素的大小: div { resize:both; overflow: ...