bzoj 1414: [ZJOI2009]对称的正方形 manacher算法+單調隊列
1414: [ZJOI2009]对称的正方形
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 331 Solved: 149
[Submit][Status]
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
- manacher算法中忘記更行mx,id變量,導致其退化成O(n^2),在這個問題調試的時候我確信了manacher算法複雜度是嚴格O(n)的。
- 單調隊列中兩相鄰元素所夾區間應屬於後面一個元素。
- 這樣得題數組大小一定要準確,如果所有下標範圍都開大一倍一定會MLE
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<string>
#include<queue>
using namespace std;
#ifdef WIN32
#define LL "%I64d"
#else
#define LL "%lld"
#endif
#define MAXN 2100
#define MAXV MAXN*2
#define MAXE MAXV*2
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3fLL
typedef long long qword;
inline int nextInt()
{
char ch;
int x=;
bool flag=false;
do
ch=(char)getchar(),flag=(ch=='-')?true:flag;
while(ch<''||ch>'');
do x=x*+ch-'';
while (ch=(char)getchar(),ch<='' && ch>='');
return x*(flag?-:);
} int n,m;
typedef int arr_t[MAXN];
typedef int arr2[MAXN*];
typedef arr_t map_t[MAXN];
map_t a,b;
map_t sa,sb,tsb,tsa; void manacher(arr2 seq,int n,arr2 &res)
{
int id,mx;
int i,j;
id=mx=-;
int cnt=;
for (i=;i<n;i++)
{
if (i<mx)
{
res[i]=min(mx-i,res[id*-i]);
}else res[i]=;
while (i-res[i]->= && i+res[i]+<n && seq[i+res[i]+]==seq[i-res[i]-])
{
res[i]++;
//cnt++;
}
if (i+res[i]>mx)//Do not forget
{
mx=i+res[i];
id=i;
}
}
return ;
}
void init_p(map_t mp,int n,int m,map_t &sl)
{
int i,j;
arr2 seq,res;
for (i=;i<n;i++)
{
for (j=;j<m;j++)
{
seq[j*+]=mp[i][j];
seq[j*]=-INF;
}
seq[*m]=-INF;
manacher(seq,*m+,res);
for (j=;j<m;j++)
{
sl[i][j]=res[j*+];
}
}
}
int pseq[MAXN];
int head,tail;
map_t fa,fb,fc;
void pm(map_t &a)
{
int i,j;
for (i=;i<n;i++)
{
for (j=;j<m;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
printf("\n");
} void work(map_t &sa,map_t &sb,map_t &fa,int n,int m)
{
int i,j;
for (i=;i<n;i++)
for (j=;j<m/;j++)
{
swap(sb[i][j],sb[i][m-j-]);
swap(sa[i][j],sa[i][m-j-]);
}
for (i=;i<n;i++)
{
head=,tail=;
pseq[]=-;
pseq[]=;
fa[i][m-]=;
for (j=;j<m;j++)
{
while (tail>=head && sb[i][j]<sb[i][pseq[tail]])tail--;
pseq[++tail]=j;
int l,r,mid;
l=-,r=tail;
while (l+<r)
{
int mid=(l+r)>>;
if (sb[i][pseq[mid]]>=j-pseq[mid])
r=mid;
else
l=mid;
}
fa[i][m-j-]=min(j-(pseq[l]+),min(sa[i][j],sb[i][pseq[r]]));
}
}
for (i=;i<n;i++)
for (j=;j<m/;j++)
{
swap(sb[i][j],sb[i][m-j-]);
swap(sa[i][j],sa[i][m-j-]);
} for (i=;i<n;i++)
{
head=,tail=;
pseq[]=-;
pseq[]=;
fa[i][]=;
for (j=;j<m;j++)
{
while (tail>=head && sb[i][j]<sb[i][pseq[tail]])tail--;
pseq[++tail]=j;
int l,r,mid;
l=-,r=tail;
while (l+<r)
{
int mid=(l+r)>>;
if (sb[i][pseq[mid]]>=j-pseq[mid])
r=mid;
else
l=mid;
}
fa[i][j]=min(fa[i][j],min(j-(pseq[l]+),min(sa[i][j],sb[i][pseq[r]])));
}
}
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int i,j,k;
int x,y,z;
int ans=;
scanf("%d%d",&n,&m);
memset(a,INF,sizeof(a));
for (i=;i<n;i++)
{
for (j=;j<m;j++)
{
scanf("%d",&x);
a[i*+][j*+]=x;
b[j*+][i*+]=x;
}
}
n*=;m*=;n++;m++;
init_p(a,n,m,sa);
init_p(b,m,n,tsb);
for (i=;i<n;i++)
for (j=;j<m;j++)
sb[i][j]=tsb[j][i];
for (i=;i<n;i++)
{
for (j=;j<m;j++)
{
sa[i][j]/=;
sb[i][j]/=;
}
} work(sa,sb,fa,n,m); for (i=;i<n;i++)
for (j=;j<m;j++)
tsa[i][j]=a[i][j];
for (i=;i<n;i++)
for (j=;j<m;j++)
b[i][m-j-]=a[m-j-][i]=tsa[i][j];
swap(n,m);
init_p(a,n,m,sa);
init_p(b,m,n,tsb); for (i=;i<n;i++)
for (j=;j<m;j++)
sb[i][j]=tsb[j][i];
for (i=;i<n;i++)
{
for (j=;j<m;j++)
{
sa[i][j]/=;
sb[i][j]/=;
}
}
work(sa,sb,fb,n,m);
for (i=;i<n;i++)
for (j=;j<m;j++)
tsb[i][j]=fb[i][j];
swap(n,m);
for (i=;i<n;i++)
for (j=;j<m;j++)
fb[i][j]=tsb[m-j-][i]; //pm(fa);
//pm(fb);
for (i=;i<n;i++)
{
for (j=;j<m;j++)
{
fc[i][j]=max(,min(fa[i][j]-(i%==),fb[i][j]-(j%==)));
fc[i][j]=(fc[i][j]+)/;
}
}
//pm(fc);
for (i=;i<n;i++)
{
for (j=;j<m;j++)
{
if (i%+j%==)continue;
ans+=fc[i][j];
}
}
cout<<ans<<endl; }
bzoj 1414: [ZJOI2009]对称的正方形 manacher算法+單調隊列的更多相关文章
- bzoj 1414: [ZJOI2009]对称的正方形
Description Orez很喜欢搜集一些神秘的数据,并经常把它们排成一个矩阵进行研究.最近,Orez又得到了一些数据,并已经把它们排成了一个n行m列的矩阵.通过观察,Orez发现这些数据蕴涵了一 ...
- 【bzoj 1414】对称的正方形 单调队列+manacher
Description Orez很喜欢搜集一些神秘的数据,并经常把它们排成一个矩阵进行研究.最近,Orez又得到了一些数据,并已经把它们排成了一个n行m列的矩阵.通过观察,Orez发现这些数据蕴涵了一 ...
- 【BZOJ1414】[ZJOI2009]对称的正方形(哈希)
[BZOJ1414][ZJOI2009]对称的正方形(哈希) 题面 BZOJ 洛谷 题解 深思熟虑一波,发现一个矩阵如果左右对称的话,那么它每行都是一个回文串,同理,如果上下对称的话,那么每列都是一个 ...
- 【BZOJ1414/3705】[ZJOI2009]对称的正方形 二分+hash
[BZOJ1414/3705][ZJOI2009]对称的正方形 Description Orez很喜欢搜集一些神秘的数据,并经常把它们排成一个矩阵进行研究.最近,Orez又得到了一些数据,并已经把它们 ...
- BZOJ 2342 双倍回文(manacher算法)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2342 题意:定义双倍回文串为:串的长度为4的倍数且串的前一半.后一半.串本身均是回文的. ...
- [luoguP2601] [ZJOI2009]对称的正方形(二维Hash + 二分 || Manacher)
传送门 很蒙蔽,不知道怎么搞. 网上看题解有说可以哈希+二分搞,也有的人说用Manacher搞,Manacher是什么鬼?以后再学. 对于这个题,可以从矩阵4个角hash一遍,然后枚举矩阵中的点,再二 ...
- 题解-------[ZJOI2009]对称的正方形
传送门 题目大意 找到所有的上下左右都相同的正方形. 思路:二分+二维Hash 这道题我们首先想到不能暴力判断一个正方形是否合法. 然后我们发现当一个正方形合法时,以这个正方形为中心且比它小的正方形也 ...
- manacher算法学习(求最长回文子串长度)
Manacher总结 我的代码 学习:yyb luogu题目模板 xzy的模板 #include<iostream> #include<cstdlib> #include< ...
- 【学习笔记】Manacher算法
本文部分图片来源 代码来源(代码是学姐哒.. 一.引入 Manacher算法是用来求最长回文子串的算法,时间复杂度O(n). 回文子串指的是''aacaa'',''noon'',这种正着反着读都一样的 ...
随机推荐
- JQuery Kendo UI使用技巧总结
Kendo UI开发总结 By Gloomyfish on 2013-04-25 在Grid中支持分页刷新: scrollable: {virtual : true }, 在Gr ...
- oracle3
查看表结构 DESC emp; 查询所有列 SELECT * FROM dept; 切忌动不动就用select * set timing on; 打开显示操作时间的开关,在下面显示查询时间. CREA ...
- Android自定义DataTimePicker(日期选择器)
实现的效果就是在同一个布局上显示日期选择和时间选择,时间不准确bug修复 1.自定义类DateTimePickDialogUtil.java public class DateTimePickDial ...
- Google Map API v2 番外篇 关于gps位置偏差及修正方法探讨
我的手机是M35C,在我自己的map activity中,通过gps获取到的经纬度比实际地址总是有500米左右的偏差. 在网上搜索了很多,都说这个是测绘局为了保密故意弄成这样的.gps全球定位系统获得 ...
- Silverlight OOB 程序自动更新
Silverlight OOB 程序 提供了非常方便的自动更新功能! 要让 Silverlight OOB 安装到客户端电脑后实现自动更新,必须实现以下两个条件: 一.为 程序的 xap 文件进行签 ...
- centos7安装chrome的历程(fedora同)
安装 首先是下载,地址奉上:http://www.google.cn/chrome/browser/desktop/index.html,选择64 bit .rpm (适用于 Fedora/openS ...
- 程序员带你十天快速入门Python,玩转电脑软件开发(二)
关注今日头条-做全栈攻城狮,学代码也要读书,爱全栈,更爱生活.提供程序员技术及生活指导干货. 如果你真想学习,请评论学过的每篇文章,记录学习的痕迹. 请把所有教程文章中所提及的代码,最少敲写三遍,达到 ...
- Gym 100187A-Potion of Immortality
题意:有n个药瓶,里面有一个有毒,然后每次拿兔子去试吃k瓶并且只能是k瓶,如果兔子死了就知道那瓶是毒药了,现在问你最少兔子要试吃几次. 分析:这题卡了好久,其实很简单.先考虑肯定要吃n/k次,那么剩下 ...
- ionic 项目分享No.2——简化版【转】
写在文章前:由于最近研究ionic框架,深感这块的Demo寥寥可数,而大家又都藏私,堂堂天朝,何时才有百家争鸣之象,开源精神吾辈当仁不让! ...
- WPF中窗口控件的跨线程调用
在WinForm中,我们要跨线程访问窗口控件,只需要设置属性CheckForIllegalCrossThreadCalls = false;即可. 在WPF中要麻烦一下,同样的不允许跨线程访问,因为没 ...