https://codeforces.com/contest/1080/problem/E

题意

有一个n*m(<=250)的字符矩阵,对于每个子矩阵的每一行可以任意交换字符的顺序,使得每一行每一列都是一个回文串,问最多有多少个这样的子矩阵

思路

  • 首先可以思考如何暴力,枚举四个边界(子矩阵),然后判定一下子矩阵的每一行每一列,这样的复杂度是nmnmn*m
  • 很明显需要找一下规律来优化一下复杂度,
    1. 对于每一行来说,最多只能存在一种字母的数量是奇数,这样一定可以保证这一行是回文串
    2. 对于每一列来说,因为不能交换顺序,所以必须具有回文性质(关于中心点对称),这就需要要求每一行相同的字母数量应该相同
  • 根据第二个规律,因为只需要验证每一行是否相同,所以可以采用字符串hash每一行,O(n*m)处理,O(1)验证
  • 首先枚举列的两个端点 O(mm),然后o(n)找出所有连续的回文行,跑马拉车算法,求出连续的回文行中所有的回文子行,O(n),总复杂度O(mm*n)
  • 符合回文性质的都可以用马拉车求出最长回文字串,回文字串个数
  1. #include<bits/stdc++.h>
  2. #define ll long long
  3. #define M 605
  4. #define key 233
  5. #define P 1000000007
  6. using namespace std;
  7. int n,m,i,j,a[M][M],c1,c2,l1,l2,msk[M],cnt[M][30],x,ans=0,d1[M],d2[M];
  8. char s[M];
  9. ll hs[M],p[M],tp[M];
  10. int ck(int x){
  11. return (x==0)||((x&(x-1))==0);
  12. }
  13. void init(){
  14. p[0]=1;for(int i=1;i<=30;i++)p[i]=p[i-1]*key%P;
  15. }
  16. int cal(int l1,int l2){
  17. int n=0,ans=0;
  18. for(int i=l1;i<=l2;i++)tp[++n]=hs[i];
  19. int l=0,r=0,x;
  20. for(int i=1;i<=n;i++){
  21. if(i>r)x=1;
  22. else x=min(d1[l+r-i],r-i);
  23. while(i-x>=1&&i+x<=n&&tp[i-x]==tp[i+x])x++;
  24. d1[i]=x;
  25. ans+=d1[i];
  26. if(i+x-1>r){r=i+x-1;l=i-x+1;}
  27. }
  28. l=r=0;
  29. for(int i=1;i<=n;i++){
  30. if(i>r)x=0;
  31. else x=min(d2[l+r-i+1],r-i+1);
  32. while(i-x-1>=1&&i+x<=n&&tp[i-x-1]==tp[i+x])x++;
  33. d2[i]=x;
  34. ans+=d2[i];
  35. if(i+x>=r){l=i-x;r=i+x-1;}
  36. }
  37. return ans;
  38. }
  39. int main(){
  40. init();
  41. cin>>n>>m;
  42. for(i=1;i<=n;i++){
  43. scanf("%s",s+1);
  44. for(j=1;j<=m;j++){
  45. a[i][j]=s[j]-'a';
  46. }
  47. }
  48. for(c1=1;c1<=m;c1++){
  49. for(i=1;i<=n;i++){
  50. hs[i]=0;msk[i]=0;
  51. memset(cnt[i],0,sizeof(cnt[i]));
  52. }
  53. for(c2=c1;c2<=m;c2++){
  54. for(i=1;i<=n;i++){
  55. x=a[i][c2];
  56. if(cnt[i][x]){
  57. hs[i]-=cnt[i][x]*p[x+1]%P;
  58. if(hs[i]<0)hs[i]+=P;
  59. }
  60. cnt[i][x]++;
  61. hs[i]+=cnt[i][x]*p[x+1]%P;hs[i]%=P;
  62. msk[i]^=(1<<x);
  63. }
  64. l1=1;
  65. while(l1<=n){
  66. if(!ck(msk[l1])){l1++;continue;}
  67. l2=l1;
  68. while(l2<=n&&ck(msk[l2]))l2++;
  69. l2--;
  70. ans+=cal(l1,l2);
  71. l1=l2+1;
  72. }
  73. }
  74. }
  75. cout<<ans;
  76. }

Codeforces Round #524 (Div. 2) E. Sonya and Matrix Beauty(字符串哈希,马拉车)的更多相关文章

  1. Codeforces Round #495 (Div. 2) D. Sonya and Matrix

    http://codeforces.com/contest/1004/problem/D 题意: 在n×m的方格中,选定一个点(x,y)作为中心点,该点的值为0,其余点的值为点到中心点的曼哈顿距离. ...

  2. Codeforces Round #524 (Div. 2)(前三题题解)

    这场比赛手速场+数学场,像我这样读题都读不大懂的蒟蒻表示呵呵呵. 第四题搞了半天,大概想出来了,但来不及(中途家里网炸了)查错,于是我交了两次丢了100分.幸亏这次没有掉rating. 比赛传送门:h ...

  3. Codeforces Round #524 (Div. 2) Solution

    A. Petya and Origami Water. #include <bits/stdc++.h> using namespace std; #define ll long long ...

  4. Codeforces Round #371 (Div. 1) C. Sonya and Problem Wihtout a Legend 贪心

    C. Sonya and Problem Wihtout a Legend 题目连接: http://codeforces.com/contest/713/problem/C Description ...

  5. Codeforces Round #371 (Div. 2) C. Sonya and Queries 水题

    C. Sonya and Queries 题目连接: http://codeforces.com/contest/714/problem/C Description Today Sonya learn ...

  6. Codeforces Round #371 (Div. 2) C. Sonya and Queries —— 二进制压缩

    题目链接:http://codeforces.com/contest/714/problem/C C. Sonya and Queries time limit per test 1 second m ...

  7. Codeforces Round #371 (Div. 2)E. Sonya and Problem Wihtout a Legend[DP 离散化 LIS相关]

    E. Sonya and Problem Wihtout a Legend time limit per test 5 seconds memory limit per test 256 megaby ...

  8. Codeforces Round #371 (Div. 2) C. Sonya and Queries[Map|二进制]

    C. Sonya and Queries time limit per test 1 second memory limit per test 256 megabytes input standard ...

  9. Codeforces Round #495 (Div. 2) C. Sonya and Robots

    http://codeforces.com/contest/1004/problem/C 题意: 在一行上有n个数字,现在在最左边和最右边各放置一个机器人,左右机器人各有一个数字p和q.现在这两个机器 ...

随机推荐

  1. RocketMq --consumer自动实现负载均衡

    这边使用一个producer和两个consumer是实现负载均衡. 看一下代码示例 package com.alibaba.rocketmq.example.message.model; import ...

  2. 项目总结11:Centos部署JDK+Tomcat+MySQL文档(阿里云-网易云-华为云)

      (如果不是root登陆,则输入:sudo su - 切换成root) 1.JDK安装 1-1-yum update (升级所有包同时也升级软件和系统内核) --安装中会有提示输入y就好(两个y,中 ...

  3. ubuntu下安装nginx1.11.10

    (本页仅作为个人笔记参考) 为openssl,zlib,pcre配置编译 wget http://om88fxbu9.bkt.clouddn.com/package/nginx/nginx-1.11. ...

  4. Python爬虫项目--爬取猫眼电影Top100榜

    本次抓取猫眼电影Top100榜所用到的知识点: 1. python requests库 2. 正则表达式 3. csv模块 4. 多进程 正文 目标站点分析 通过对目标站点的分析, 来确定网页结构,  ...

  5. JS 获取屏幕的宽度和高度,各种方式

      Javascript: 网页可见区域宽: document.body.clientWidth网页可见区域高: document.body.clientHeight网页可见区域宽: document ...

  6. @Transational)的方法,注解失效的原因和解决方法

    在同一个类中,一个方法调用另外一个有注解(比如@Async,@Transational)的方法,注解是不会生效的. 比如,下面代码例子中,有两方法,一个有@Transational注解,一个没有.如果 ...

  7. 工作中用Git对项目进行管理

    前言 之前一直是用svn来管理代码的,今天第一次用git来管理代码,从安装.上传代码过程中遇到了很多问题,Github中建的repository之前还是https协议,最后不知道怎么又变成了git协议 ...

  8. MongoDb进阶实践之八 MongoDB的聚合初探

    一.引言 好久没有写东西了,MongoDB系列的文章也丢下好长时间了.今天终于有时间了,就写了一篇有关聚合的文章.一说到“聚合”,用过关系型数据库的人都应该知道它是一个什么东西.关系型数据库有“聚合” ...

  9. 三分钟分布式CAP理论

    分布式系统架构理论,定义了三种指标,理论说我们最多只能满足两个. ## 分布式系统 首先我们这个理论所说的分布式系统,是指系统内会共享数据,互相有连接有交互,才能完成系统功能的的分布式系统.而这个理论 ...

  10. 06. pt-duplicate-key-checker

    | t01 | CREATE TABLE `t01` ( `pkid` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT ...