CodeForces - 1051E :Vasya and Big Integers(Z算法 & DP )

Posted hua-dong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CodeForces - 1051E :Vasya and Big Integers(Z算法 & DP )相关的知识,希望对你有一定的参考价值。

题意:给定字符串S,A,B。现在让你对S进行切割,使得每个切割出来的部分在[A,B]范围内,问方案数。

思路:有方程,dp[i]=Σ dp[j]   (S[j+1,i]在合法范围内)。    假设M和N的最长公共前缀为长度是LCP,那么字符串M>=字符串N的条件是  LCP=|N|或者(LCP<|N|&&M[lcp+1]>N[lca+1]); 小于同理。 求出范围就可以用前缀和 O(N)求DP了。

而LCP显然可以用exkmp求。 最近发现Z算法比较好写。  尝试了一下。  这里把两个串连起来一次性求,看起来比较舒服。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=1000010;
const int Mod=998244353;
char s[maxn<<1],l[maxn],r[maxn];
int z1[maxn],z2[maxn],lena,lenl,lenr;
void Z(char a[],char t[],int z[])

    int f=strlen(a+1),w=strlen(t+1);
    a[f+1]=&; rep(i,1,w) a[f+1+i]=t[i]; int n=f+w+1;
    z[1]=n; int L=0,R=0;
    rep(i,2,n) 
        if(R<i) z[i]=0;
        else z[i]=min(R-i+1,z[i-L+1]);
        while(i+z[i]<=n&&a[i+z[i]]==a[z[i]+1]) z[i]++;
        if(i+z[i]-1>R) L=i,R=i+z[i]-1;
    
    rep(i,1,w) z[i]=z[f+1+i];

int dp[maxn],sum[maxn];
int main()

    scanf("%s%s%s",s+1,l+1,r+1);
    lena=strlen(s+1); lenl=strlen(l+1); lenr=strlen(r+1);
    Z(l,s,z1); Z(r,s,z2);
    dp[lena+1]=sum[lena+1]=1;
    for(int i=lena;i>=1;i--) 
        sum[i]=sum[i+1];
        if(s[i]==0) dp[i]=(l[1]==0)*dp[i+1],sum[i]=(sum[i]+dp[i])%Mod;
        else 
            int L=i+lenl,R=min(i+lenr-2,lena);
            if(z1[i]==lenl||s[i+z1[i]]>l[z1[i]+1]) L--;
            if(R<lena&&(z2[i]==lenr||s[i+z2[i]]<r[z2[i]+1])) R++;
            if(L<=R) dp[i]=(sum[L+1]-sum[R+2]+Mod)%Mod,sum[i]=(sum[i]+dp[i])%Mod;
        
    
    printf("%d\n",dp[1]);
    return 0;

 

以上是关于CodeForces - 1051E :Vasya and Big Integers(Z算法 & DP )的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces - 837E - Vasya's Function | Educational Codeforces Round 26

Vasya And Password(CodeForces - 1051A)

Codeforces 837E. Vasya's Function

CodeForces - 1016D Vasya And The Matrix

Codeforces 837E Vasya's Function - 数论

[Codeforces 1058E] Vasya and Good Sequences