【NOI2016】优秀的拆分 题解(95分)

题目大意:

  求一个字符串中形如AABB的子串个数。

思路:

  用哈希做到O(1)判断字符串是否相同,O($n^2$)预处理,ans[i]为开头位置为i的形如AA的子串个数。再用O($n^2$)枚举出AABB中的AA,加上BB(已预处理)的个数即可。时间复杂度为O($n^2$),最后一个点过不掉~~。(此方法为在下所想的朴素算法,比不得大神们的方法,代码更是烂得要死)

代码:

 #include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int S=,mod=;
char s[];
long long ans[],Hash[],mi[]; int gethash(int l,int r)
{
return (Hash[r]-Hash[l-]*mi[r-l+]%mod+mod)%mod;
} int main()
{
int n;
scanf("%d",&n);
while (n--)
{
int cnt,i,j;
long long sum=;
scanf("%s",s+); cnt=strlen(s+);
for (i=;i<=cnt;i++) Hash[i]=(Hash[i-]*S+s[i]-'a'+)%mod;
for (mi[]=i=;i<=cnt;i++) mi[i]=mi[i-]*S%mod;
for (i=;i<=cnt;i++) ans[i]=;
for (i=;i<=cnt;i++)
for (j=i;j+j-i+<=cnt;j++)
if (gethash(i,j)==gethash(j+,j+j-i+)) ans[i]++;
for (i=;i<cnt-;i++)
for (j=i;j>i+>>;j--)
if (gethash(j,i)==gethash(j-i+j-,j-)) sum+=ans[i+];
printf("%d\n",sum);
}
return ;
}
上一篇:JS限制input输入的为数字并且有小数的时候最多保留两位小数


下一篇:Django项目部署在Linux下以进程方式启动