题面戳我

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!!!

【题解】 Codeforces Edu41 F. k-substrings (字符串Hash)的更多相关文章

  1. codeforces gym 101164 K Cutting 字符串hash

    题意:给你两个字符串a,b,不区分大小写,将b分成三段,重新拼接,问是否能得到A: 思路:暴力枚举两个断点,然后check的时候需要字符串hash,O(1)复杂度N*N: 题目链接:传送门 #prag ...

  2. 【题解】 bzoj3916: [Baltic2014]friends (字符串Hash)

    题面戳我 Solution 首先长度为偶数可以直接判掉 然后我们可以枚举删的位置,通过预处理的\(hash\),判断剩余部分是否划分成两个一样的 判重要注意,我们把字符串分为三个部分\(L_l+1+L ...

  3. 【题解】 Codeforces Edu44 F.Isomorphic Strings (字符串Hash)

    题面戳我 Solution 我们按照每个字母出现的位置进行\(hash\),比如我们记录\(a\)的位置:我们就可以把位置表示为\(0101000111\)这种形式,然后进行字符串\(hash\) 每 ...

  4. 【codeforces 514C】Watto and Mechanism(字符串hash)

    [题目链接]:http://codeforces.com/contest/514/problem/C [题意] 给你n个字符串; 然后给你m个询问;->m个字符串 对于每一个询问字符串 你需要在 ...

  5. LA4671 K-neighbor substrings(FFT + 字符串Hash)

    题目 Source http://acm.hust.edu.cn/vjudge/problem/19225 Description The Hamming distance between two s ...

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

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

  7. CodeForces 1056E - Check Transcription - [字符串hash]

    题目链接:https://codeforces.com/problemset/problem/1056/E One of Arkady's friends works at a huge radio ...

  8. 线段树 + 字符串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]是 ...

  9. Codeforces 898F - Restoring the Expression(字符串hash)

    898F - Restoring the Expression 思路:字符串hash,base是10,事实证明对2e64取模会T(也许ull很费时),对1e9+7取模. 代码: #include< ...

随机推荐

  1. vue2.0中使用pug(jade)

    第一部分:pug(jade)模板引擎 pug,原名jade,是流行的HTML模板引擎,它是HAML在JavaScript上的实现,最大的特色是使用缩进排列替代成对标签. 它简化了HTML的成对标签的写 ...

  2. ES6 Promise 异步操作

    最近越来越喜欢与大家进行资源分享了,并且及时的同步到自己的园子内,为什么呢? 一.小插曲(气氛搞起) 在上个月末,由于领导的高度重视(haha,这个高度是有多高呢,185就好了),走进了公司骨干员工的 ...

  3. 我的物联网项目专题移到网站:http://51jdk.com

    我的物联网项目专题移到网站:http://51jdk.com

  4. [UWP 自定义控件]了解模板化控件(10):原则与技巧

    1. 原则 推荐以符合以下原则的方式编写模板化控件: 选择合适的父类:选择合适的父类可以节省大量的工作,从UWP自带的控件中选择父类是最安全的做法,通常的选择是Control.ContentContr ...

  5. Awesome Python,Python的框架集合

    Awesome Python A curated list of awesome Python frameworks, libraries and software. Inspired by awes ...

  6. 金蝶PDA金蝶盘点机金蝶仓库条码管理方案-采购入库单教程

    采购入库单有两种做法: 第一种:按照采购订单下推的采购入库单. 第二种:直接新增采购入库单,也就是不按照采购订单下推. 按照采购订单下推生成采购入库单,会以采购订单的商品品种和数量作为应收.扫描条码入 ...

  7. Linux系统本地yum源环境配置记录

    由于IDC的一些服务器没有外网,不能对外访问.所以打算部署一套内网的yum源环境,以供内网服务器使用.以下简单记录下操作过程: 1)下载centos6.9和centos7.3的镜像,并挂载 [root ...

  8. Pair Project —— Elevator Scheduler

    结对编程人员 12061153 刘丽萍 12061154 冯飘飘 说明结对编程的优点和缺点. 结对编程的优点: 以前都是自己一个人编程,对于相互结对或者团队编程都没有接触过.而自己在写代码时不可避免的 ...

  9. Week7阅读笔记

    关于银弹: Brooks在他最著名的这篇文章里指出,在软件开发过程里是没有万能的终杀性武器的,只有各种方法综合运用,才是解决之道.而各种声称如何如何神奇的理论或方法,都不是能杀死“软件危机”这头人狼的 ...

  10. C#【结对编程作业】小学数学习题助手

    一.软件成品展示 软件本体下载(包括程序及其更新日志,源码工程包,UML图,API接口文档,算法介绍文档,算式计算excel实例,浅查重程序) 链接: http://pan.baidu.com/s/1 ...