Luogu4548 singing Kingdom

Luogu4548 singing Kingdom

Questions surface: Luogu

Resolve

It's an interesting topic.

A class of generating function for a discrete random variable Integer \ (T \) , each item of the function \ (x ^ i \) coefficient represents the value of variable \ (I \) is the probability, also It is:

\[f(x)=\sum_{i=0}^{\infty} P(t=i)x^i\]

This function has a number of interesting properties, such as: \ (F (. 1). 1 = \)
and for \ (T \) is desirable to have: \ (E (T) = F '(. 1) \)

This question is now to make \ (n-\) represents the alphabet size, \ (m \) represents the length of the name.

Consider setting \ (F (x) \) means that for the singing of \ (I \) numbers ending probability generating function, \ (G (X) \) means that for the singing of \ (I \) digits not the end of the probability of generating function.

Obviously there is the following formula:

\[xG(x)+1=F(x)+G(x)\]

That is not the end of the string and then connected to a character, it may end, or may not end.

Secondly, there are:

\[G(x) \Big(\frac{1}{n}x\Big)^m=\sum_{i=1}^{m}a_{i}F(x)\Big(\frac{1}{n}x\Big)^{m-i}\]

That is connected after the end of the name string will not end, but it may end before the advance, where \ (A_ {I} = 0 /. 1 \) , represents \ (s [1, i] \) whether string \ (S \) a \ (border \) .

The first derivative of the formula and simplification, there are:

\[F'(x)=(x-1)G'(x)+G(x)\]

In the second equation into the \ (X =. 1 \) , are:

\[G(1)=\sum_{i=1}^{m} a_{i} n^{i}\]

and so:

\[E(x)=F'(1)=G(1)=\sum_{i=1}^m a_{i} n^{i}\]

For \ (A_ {I} \) , \ (KMP \) seek to.

Code


#include<cstdio>
#define N 100005

using namespace std;

inline int In(){
    char c=getchar(); int x=0,ft=1;
    for(;c<'0'||c>'9';c=getchar()) if(c=='-') ft=-1;
    for(;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';
    return x*ft;
}

const int P=10000;
int n,T,m,s[N],nex[N],pw[N];

int main(){
    n=In(); T=In();
    while(T--){
        m=In(); for(int i=1;i<=m;++i) s[i]=In();
        pw[0]=1; for(int i=1;i<=m;++i) pw[i]=pw[i-1]*n%P;
        for(int i=2,j=0;i<=m;++i){
            while(j&&s[j+1]!=s[i]) j=nex[j];
            if(s[j+1]==s[i]) ++j; nex[i]=j;
        }
        int sum=0;
        for(int i=m;i;i=nex[i]) sum=(sum+pw[i])%P;
        printf("%.4d\n",sum);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/pkh68/p/11404703.html