codeforces 494B Obsessive String

来源:互联网 发布:美国和英国关系知乎 编辑:程序博客网 时间:2024/06/06 15:43

题目意思让我读了好久,可怜我渣渣英语。 题意大概是 先给你一个串 S  然后再给你一个串 T ,那么如果一个集合,这个集合里面有一些串  分别为 a1,a2,a3,a4...ax

如果 这些串都属于 S的子串并且 这些串不能含有相同的第某个字符,即是不能重复   且 T 也是这些串每个串的子串,那么这个集合就是一个合法集合,问有多少个合法集合

举个例子吧  ababa  和 aba   那么符合条件的集合 有5个  分别 是   { aba }  ,{abab} ,{ababa}. {baba},{aba}. 

首先  考虑 DP[I] 表示 以 i 为起点 必须包含 i 的到串尾的 合法集合的个数 

那么先用KMP记录出 以I 开头 长为 |T|  刚好匹配  记为 fg[i]=1;  i从 0到 n-1;

然后 当 fg[i] 为  0 时  就为 dp[i] =dp[i+1]

如果 当 fg[i] 为 1  那么  dp[i]=n-i-m+1  dp[i]+=dp[i+m]+d[i+m+1]*2+dp[i+m+2]*3...

后面这些东西 可以用 前缀和的前缀和 统计


代码如下

#include<iostream>#include<algorithm>#include<stdio.h>#include<string.h>using namespace std;typedef long long LL;#define mod 1000000007#define NN 200000LL dp[NN+10];char mo[NN+10],s[NN+10];int next[NN+10],fg[NN+10];LL sum1[NN+10],sum2[NN+10];void get_next(int m){    next[0]=next[1]=0;    for(int i=1;i<m;i++)    {        int j=next[i];        while(j && mo[i]!=mo[j]) j=next[j];        next[i+1]= mo[i]==mo[j]?j+1:0;    }}void Find(int n,int m){    int j=0;    for(int i=0;i<n;i++)    {        while(j && mo[j]!=s[i]) j=next[j];        if(mo[j]==s[i]) j++;        if(j==m)        {            j=next[j];            fg[i-m+1]=1;        }    }}int main(){    while(scanf("%s",s)!=EOF)    {        scanf("%s",mo);        int m=strlen(mo);        int n=strlen(s);        memset(fg,0,sizeof(fg));        memset(sum1,0,sizeof(sum1));        memset(sum2,0,sizeof(sum2));        memset(dp,0,sizeof(dp));        get_next(m);        Find(n,m);        for(int i=n-1;i>=0;i--)        {            if(fg[i]==1)            {                dp[i]+=n-i-m+1;                dp[i]%=mod;                if(i+m <= n)                    dp[i]=(dp[i]+sum2[i+m])%mod;                sum1[i]=(sum1[i+1]+dp[i])%mod;                sum2[i]=(sum2[i+1]+sum1[i])%mod;            }            else            {                dp[i]=dp[i+1];                sum1[i]=(sum1[i+1]+dp[i])%mod;                sum2[i]=(sum2[i+1]+sum1[i])%mod;            }        }        LL ans=0;        for(int i=0;i<n;i++)        {            ans=(ans+dp[i])%mod;        }        printf("%lld\n",ans);    }    return 0;}


0 0