Codeforces 535D Tavas and Malekas-字符串匹配

时间:2022-02-03 06:32:34

传送门

题意:

给出文本串的长度n,给出模式串以及模式串在文本串中出现的位置,求有多少种文本串满足条件。

Solution:

在文本串中暴力加入模式串,最后判断匹配位置是否和给出的相符即可。

代码(z-box赛高!):

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
int z[2000010],n,m,r,l,p;
char b[2000010],a[1000010];
int maxn=0,ar,x;
int ans[1000010];
int wei;
const int mod=1e9+7;
int fast_pow(int a,int x)
{
    int ans=1;
    for (;x;x>>=1,a=1ll*a*a%mod) 
        if (x&1) ans=1ll*ans*a%mod;
    return ans;
}
int main()
{
    scanf("%d%d",&n,&p); 
    scanf("%s",b);
    int len=strlen(b);
    for (int i=1;i<=p;i++)
    {
        scanf("%d",&x);
        ans[i]=x;
        if (x>ar)
        {
            for (int j=0;j<len&&x+j<=n;j++)
                a[x+j]=b[j];
            ar=x+len-1;
        }
        else
        {
            for (int j=ar-x+1;j<len&&x+j<=n;j++)
                a[x+j]=b[j];
            ar=x+len-1;
        }
    }
    b[len]='$';
    for (int i=1;i<=n;i++)
    {
        b[len+i]=a[i];
        if (a[i]<'a') wei++;
    }
    for (int i=1;i<=len+n;i++)
    {
        if (i>r)
        {
            int t=i,bg=0;
            while (b[t]==b[bg])
                t++,bg++;
            z[i]=bg;
            r=t-1;
            l=i;
        }
        else
        {
            if (z[i-l]<r-i+1) z[i]=z[i-l];
            else
            {
                int t=r+1,bg=r-i+1;
                while (b[t]==b[bg])
                    t++,bg++;
                z[i]=bg;
                r=t-1;
                l=i;
            }
        }
    }
    for (int i=1;i<=p;i++)
        if (z[ans[i]+len]<len) {printf("0");return 0;}
    printf("%d",fast_pow(26,wei));
}