题面戳我

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. pycharm 取消 rebase 操作

    291/5000 取消rebase操作从主菜单中选择VCS | Git | 中止重新定位(abrot rebasing)如果rebase在两个或多个本地存储库中启动,则会显示“中止重新排序”对话框. ...

  2. Luogu4099 HEOI2013 SAO 组合、树形DP

    传送门 值得注意的是一般的DAG的拓扑序列数量是NP问题,所以不能直接入手 题目中给出的图可以看做是一个树形图,虽然方向比较迷.考虑使用树形图的性质 不妨任选一个点为根做树形DP,注意到数的位置与方案 ...

  3. CF1038E Maximum Matching 搜索/区间DP

    题目传送门:http://codeforces.com/problemset/problem/1038/E 题意:给出$N$个方块,每个方块有左右两种颜色$a,b$(可以翻转使左右两种颜色交换)和一个 ...

  4. C#实现一张塔松叶

    前段时间,Insus.NET有实现一组字符串在输出时,靠左或靠右对齐.<输出的字符靠右对齐>http://www.cnblogs.com/insus/p/7953304.html 现在In ...

  5. 微信小程序 wx.getUserInfo 解密 C# 代码 - 转

    public static string DecodeUserInfo(string raw, string signature,string encryptedData, string iv) { ...

  6. Ionic下的JPush缺少统计代码问题解决方法

    用Ionic打包apk后安装到手机,收到缺少统计代码的提示,解决方法如下: 1. 找到了 platforms/android/src/com/ionichina/ioniclub/MainActiov ...

  7. python中和生成器协程相关yield from之最详最强解释,一看就懂(二)

    一. 从列表中yield  语法形式:yield from <可迭代的对象实例> python中的列表是可迭代的, 如果想构造一个生成器逐一产生list中元素,按之前的yield语法,是在 ...

  8. LInux下设置账号有效时间 以及 修改用户名(同时修改用户组名和家目录)

    在linux系统中,默认创建的用户的有效期限都是永久的,但有时候,我们需要对某些用户的有效期限做个限定!比如:公司给客户开的ftp账号,用于客户下载新闻稿件的.这个账号是有时间限制的,因为是付费的.合 ...

  9. centos7下部署iptables环境纪录(关闭默认的firewalle)

    CentOS7默认的防火墙不是iptables,而是firewall.由于习惯了用iptables作为防火墙,所以在安装好centos7系统后,会将默认的firewall关闭,并另安装iptables ...

  10. bash处理一条命令的步骤

    Shell执行一条命令步骤 参考链接: <Learning the bash Shell, 3rd Edition  -- 7.3. Command-Line Processing> &l ...