「CTSC2006」歌唱王国

概率生成函数(g(x)=sum_{igeq 0}t_ix^i)(t_i)表示结果为(i)的概率

(f(x))表示i位表示串结束时长度为i的概率,(G(x))表示i位表示串长度为i时不结束的概率

有如下关系

[①:f(x)+g(x)=1+g(x)x ]

意义:(f(x)+g(x))即为串长达(i)位的概率,即(i-1)位不结束的概率

定义一个字符串的border为一个既为它前缀又为它后缀的非空串

定义(b_i)表示([[1,2,cdots,i] ext{为给定串border}]),设给定串长度为L

那么可以得到

[②:g(x) imes ({1over n}x)^{L}=sum_{i=1}^L b_i imes f(x) imes ({1over n}x)^{L-i} ]

意义:左边:在一个串后添加给定串,必然结束。右边:长i的border,使得串在添加到i个字符时结束后,仍会添加剩下的(L-i)个字符

[① o f^{'}(x)+g^{'}(x)=g^{'}(x)x+g(x) ]

(x=1)带入,(f^{'}(1)=g(1)),而(f^{'}(1))即为答案

[② o g(1)=sum_{i=1}^L b_i f(1)n^i ]

(f(1)=1),故(displaystyle g(1)=sum_{i=1}^L b_in^i)

故答案为(sum_{i=1}^L b_in^i)


#include <bits/stdc++.h>
//#pragma GCC target("avx,avx2,sse4.2")
#define rep(q, a, b) for (int q = a, q##_end_ = b; q <= q##_end_; ++q)
#define dep(q, a, b) for (int q = a, q##_end_ = b; q >= q##_end_; --q)
#define mem(a, b) memset(a, b, sizeof a)
#define debug(a) cerr << #a << ' ' << a << "___" << endl
using namespace std;
// char buf[10000000], *p1 = buf, *p2 = buf;
#define Getchar() getchar()//p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 10000000, stdin), p1 == p2) ? EOF : *p1++
void in(int &r) {
    static char c;
    r = 0;
    while (c = Getchar(), c < 48);
    do
        r = (r << 1) + (r << 3) + (c ^ 48);
    while (c = Getchar(), c > 47);
} 
const int mn=100005;
int n,T,len;
int as[mn];
const int base=100003;
const int mod=998244353;
int solve(){
    int l=0,r=0,B=1,Ml=1,ans=0;
    rep(q,1,len){
        l=(1LL*l*base+as[q])%mod;
        r=(1LL*B*as[len-q+1]+r)%mod;
        B=1LL*B*base%mod;
        Ml=Ml*n%10000;
        if(l==r)ans=(ans+Ml)%10000;
    }
    return ans;
}
int main(){
    in(n),in(T);
    while(T--){
        in(len);
        rep(q,1,len)in(as[q]);
        printf("%04d
",solve());
    }
    return 0;
}
原文地址:https://www.cnblogs.com/klauralee/p/11692585.html