LG P7114 字符串匹配

Description

小 C 学习完了字符串匹配的相关内容,现在他正在做一道习题。

对于一个字符串 $S$,题目要求他找到 $S$ 的所有具有下列形式的拆分方案数:

$S = ABC$,$S = ABABC$,$S = ABAB \ldots ABC$,其中 $A$,$B$,$C$ 均是非空字符串,且 $A$ 中出现奇数次的字符数量不超过 $C$ 中出现奇数次的字符数量。

更具体地,我们可以定义 $AB$ 表示两个字符串 $A$,$B$ 相连接,例如 $A = \texttt{aab}$,$B = \texttt{ab}$,则 $AB = \texttt{aabab}$。

并递归地定义 $A^1=A$,$A^n = A^{n - 1} A$($n \ge 2$ 且为正整数)。例如 $A = \texttt{abb}$,则 $A^3=\texttt{abbabbabb}$。

则小 C 的习题是求 $S = {(AB)}^iC$ 的方案数,其中 $F(A) \le F(C)$,$F(S)$ 表示字符串 $S$ 中出现奇数次的字符的数量。两种方案不同当且仅当拆分出的 $A$、$B$、$C$ 中有至少一个字符串不同。

小 C 并不会做这道题,只好向你求助,请你帮帮他。

Solution

预处理每个前缀和后缀的奇数字符个数

枚举$AB$的数次方,检验时使用哈希,每次对答案的贡献为$(AB)^i$可以被分成使$A$满足要求的方案数

时间复杂度$O(n \log n)$,勉强能过,使用exKMP可以达到$O(n)$,不会

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
short T,pre[1050005],suf[1050005],buc[30];
int n,vst[30];
long long ans;
unsigned long long base[1050005]={1},has[1050005];
char s[1050005];
inline int read()
{
    int f=1,w=0;
    char ch=0;
    while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=getchar();
    return f*w;
}
int main()
{
    T=read();
    for(int i=1;i<=1050000;i++) base[i]=base[i-1]*31;
    for(;T;T--)
    {
        scanf("%s",s+1),n=strlen(s+1),ans=0;
        memset(buc,0,sizeof(buc)),memset(vst,0,sizeof(vst)),memset(suf,0,sizeof(suf));
        for(int i=1;i<=n;i++)
        {
            buc[s[i]-'a']^=1;
            if(buc[s[i]-'a']) pre[i]=pre[i-1]+1;
            else pre[i]=pre[i-1]-1;
        }
        memset(buc,0,sizeof(buc));
        for(int i=n;i;i--)
        {
            buc[s[i]-'a']^=1;
            if(buc[s[i]-'a']) suf[i]=suf[i+1]+1;
            else suf[i]=suf[i+1]-1;
        }
        for(int i=1;i<=n;i++) has[i]=has[i-1]*31+1ull*(s[i]-'a');
        for(int i=2;i<=n;i++)
        {
            for(int j=pre[i-1];j<=26;j++) vst[j]++;
            for(int j=i;j<n&&has[i]==has[j]-has[j-i]*base[i];j+=i) ans+=vst[suf[j+1]];
        }
        printf("%lld\n",ans);
    }
    return 0;
}
字符串匹配

 

posted @ 2020-12-14 08:58  QDK_Storm  阅读(150)  评论(0编辑  收藏  举报