题面戳我

Solution

  • 我们正着每次都要枚举从长到短,时间复杂度承受不了,但是我们可以发现一个规律,假设某次的答案为\(x\),那么这个字符串为\(A+X+B\)组成,无论中间的\(X\)是重叠还是空余的,我们都可以发现,这个字符串可以改成\(a+A'+X+B'+b\),所以下一次砍掉两边,这个\(A'\)中没有\(a\)与\(B'\)匹配,\(B'\)中同理没有\(b\)与\(A'\)匹配,所以公共串长度至少\(-2\)。
  • 有了上面那个性质,我们再倒着来做,我们把砍掉两边改成在两边加上两个字符,那么这次答案,至多是上次答案\(+2\),那么答案就只能从\(lastans+2,lastans,\cdots,1\)中查找,我们如果判断到一个答案符合前缀和后缀一样,我们就可把这个数作为答案,直接\(break\)即可,长度\(1\)的子串前缀和后缀都没有答案就是\(-1\)。
  • 我们来验证下时间复杂度的正确性,因为我们每次都是从\(lastans+2\),开始然后向后减,其实就与\(KMP\)一样(我不会),减的次数由加的次数决定,然后我们加的次数不会多于\(n/2+1\),忽略常数,再加上\(Hash\),所以我们就可以证明时间复杂度大概是\(O(n)\)的了
  • 判断字符串相同用\(Hash\)

Code

//It is coded by ning_mew on 7.23
#include<bits/stdc++.h>
#define LL long long
using namespace std;const int maxn=1e6+7;int n;
char ch[maxn];
LL MOD[3]={19260817,20000909,19491001};
LL Hash[3][maxn],Pow[3][maxn];
int ans[maxn];bool check(int s,int len){int mid,t;if(n%2){mid=(n+1)/2;t=2*mid-s;}else {mid=n/2;t=mid-s+mid+1;}for(int i=0;i<3;i++){int box1=((Hash[i][s+len-1]-Hash[i][s-1]*Pow[i][len])%MOD[i]+MOD[i])%MOD[i];int box2=((Hash[i][t]-Hash[i][t-len]*Pow[i][len])%MOD[i]+MOD[i])%MOD[i];if(box1!=box2)return false;}return true;
}
void work1(){ans[(n+1)/2]=-1;for(int i=(n+1)/2-1;i>=1;i--){//cout<<"----------------------"<<endl;ans[i]=-1;for(int k=ans[i+1]+2;k>=1;k-=2){//cout<<k<<endl;if(check(i,k)){ans[i]=k;break;}}}for(int i=1;i<=(n+1)/2;i++){printf("%d ",ans[i]);} printf("\n");
}
void work2(){if(ch[n/2]==ch[n/2+1])ans[n/2]=1;else ans[n/2]=-1;for(int i=n/2-1;i>=1;i--){ans[i]=-1;for(int k=ans[i+1]+2;k>=1;k-=2){//cout<<k<<endl;if(check(i,k)){ans[i]=k;break;}}}for(int i=1;i<=n/2;i++){printf("%d ",ans[i]);} printf("\n");
}
int main(){scanf("%d",&n);scanf("%s",ch+1);for(int j=0;j<3;j++){Pow[j][0]=1;for(int i=1;i<=n;i++){Hash[j][i]=(Hash[j][i-1]*27+ch[i]-'a')%MOD[j];Pow[j][i]=Pow[j][i-1]*27%MOD[j];}}if(n%2)work1();else work2();return 0;
}

博主蒟蒻,随意转载。但必须附上原文链接:http://www.cnblogs.com/Ning-Mew/,否则你会场场比赛爆0!!!

转载于:https://www.cnblogs.com/Ning-Mew/p/9356955.html

【题解】 Codeforces Edu41 F. k-substrings (字符串Hash)相关推荐

  1. codeforces 877F F. Ann and Books hash+莫队算法

    题意:给你一堆数字,每个数字有正负之分,求任意区间内和为k的子区间的个数. 题解: 先把前缀和都求出来,构成一个数组sum. 建立一个hash表,然后考虑区间sum[l,r],从左到右扫,每扫到一个前 ...

  2. UVA4671 K-neighbor substrings FFT+字符串hash

    题解: 将字符串A.B中的a和b分别以1和-1表示,对字符串B进行反转. 将A和B看成多项式,求卷积,这样的话从结果区间的[lenB−1,lenA)[lenB−1,lenA)[lenB-1,lenA) ...

  3. 九宫重排 蓝桥杯c++ 题解 字符串hash+bfs

    九宫重排 蓝桥杯c++ 题解 字符串hash+bfs 题意:给出一个九宫格,你可以将与空格相邻的数字和空格进行交换,目的是得到另一个九宫格,问最少的步数. 思路:从最小步数不难看出我们可以使用广度优先 ...

  4. CodeForces - 727E Games on a CD 字符串Hash

    题意:有n个单词,每个单词长度为k,顺时针将它们写成一个圆圈串.现在知道g个长度为k的单词,是否可以从这g个单词中选择n个形成这个圆圈串?如果有多个答案,任意输出一个. 思路 可以发现,如果枚举第一个 ...

  5. 【Codeforces - 127D】Password(思维,二分+字符串Hash)

    题干: Asterix, Obelix and their temporary buddies Suffix and Prefix has finally found the Harmony temp ...

  6. 线段树 + 字符串Hash - Codeforces 580E Kefa and Watch

    Kefa and Watch Problem's Link Mean: 给你一个长度为n的字符串s,有两种操作: 1 L R C : 把s[l,r]全部变为c; 2 L R d : 询问s[l,r]是 ...

  7. 【Codeforces 1426 F】Number of Subsequences,字符串计数DP

    problem F. Number of Subsequences time limit per test1 second memory limit per test256 megabytes inp ...

  8. 【CodeForces - 155C】Hometask (字符串,思维,贪心,熟悉句式)(总结)

    题干: Sergey attends lessons of the N-ish language. Each lesson he receives a hometask. This time the ...

  9. 深圳神牛python培训_请教神牛_字符串hash

    针对字符串hash 我早就听闻可以暴力的干一些事情. 比如 可以... 很多很多 实现O(n)求出 模式串在文本串出现的次数. 但是我不会这什么hash. 我会自然溢出字符串hash 嘿嘿 unsig ...

最新文章

  1. 兄弟,敬你是条汉子,请干了广告们~
  2. uva 10673 ——Play with Floor and Ceil
  3. nineoldandroid使用_nineoldandroid 详细使用并且实现drawerlayout侧滑动画
  4. Python json模块 - Python零基础入门教程
  5. 【高校宿舍管理系统】第五章 JWT原理和应用以及实现功能菜单
  6. 95-136-040-源码-Operator-Operator简介
  7. 注解形式控制器 数据验证,类型转换(2)
  8. linux远程登录模拟输入输出重定向,从零开始学习Linux(三十三):Shell基础之输入输出重定向...
  9. Services in Kubernetes
  10. 微软鼠标测试软件,微软发了一款“精准”鼠标 我们告诉你精准在哪儿?
  11. 【计算理论】计算理论总结 ( 上下文无关文法 | 乔姆斯基范式 | 乔姆斯基范式转化步骤 | 示例 ) ★★
  12. 思科 计算机网络 期末考试答案
  13. 加州大学洛杉矶计算机排名,加州大学洛杉矶分校计算机科学硕士排名第14(2020年TFE Times排名)...
  14. java 坦克大战画坦克_java简易坦克大战(2)
  15. Oracle SQL 高版本相关
  16. Windows 10 64bit 安装dotnetfx 3.5出错的解决办法(备忘)
  17. 汽车凸轮轴的拆装过程
  18. JAVA 取余 余数
  19. python爬取58上的招聘信息
  20. Unicode 字符集七个字符属性

热门文章

  1. Mac brew安装maven
  2. linux通过tar包安装docker
  3. jvm的生命周期:启动、执行、退出
  4. Scala apply()方法用于创建伴生类对象
  5. 请说明一下http和https的区别
  6. 请你解释一下什么是线程池(thread pool)?
  7. MySQL主从复制详细配置步骤及复制延时问题解决
  8. Vue+Spring boot前后端响应流程总结
  9. 使用dubbo需要导入的jar包
  10. 根据Explain结果中的key_len判断MySQL联合索引中实际用到的索引字段