命运的X

命运的X

cjx 生成函数强。

思路

首先,设 fi 为添加第 i 项后满足条件的概率,gi 任意添加至第 i 项的概率。

我们要求的答案:

ans=i=0i×fi

我们把 f 放入生成函数中:

F=i=0fixi

显然有 F(1)=1

F 进行取导。

F=i=1i×fixi1

发现有 ans=F(1)

g 也用生成函数 G 表示出来。

考虑加入一个字符,那么有 xG=G+F,即可能匹配,也可能不匹配。

移项得,(x1)G=F

导一下,G+(x1)G=F

x=1,得 G(1)=F(1)

考虑对 G 做转移,每次向后添加一段 b。当然可能添加中途已经存在最后一段等于 b 的情况,我们也要考虑,那就有:

xnmnG=i=1n[i]Fxnimni

其中 i 满足,b[1,i]=b[ni+1,n]

移项得:

G=i=1n[i]Fmixi

x=1,对下式求和即可。

ans=G(1)=i=1n[i]F(1)mi

CODE

#include<bits/stdc++.h>
using namespace std;

#define ll long long
#define N 200000
#define pll pair<ll,ll>

const int maxn=2e5+5;
const ll mod=998244353,base=20090327,mod1=1e9+7,mod2=1e9+9;

int n,m;
int b[maxn];

ll pw1[maxn],pw2[maxn],sum1[maxn],sum2[maxn];

inline void init()
{
    pw1[0]=pw2[0]=1;
    for(int i=1;i<=N;i++)
        pw1[i]=pw1[i-1]*base%mod1,
        pw2[i]=pw2[i-1]*base%mod2;
}

inline pll calc(int l,int r){return {(sum1[r]-sum1[l-1]*pw1[r-l+1]%mod1+mod1)%mod1,(sum2[r]-sum2[l-1]*pw2[r-l+1]%mod2+mod2)%mod2};}
inline void solve()
{
    ll tmp=1,ans=0;
    for(int i=1;i<=n;i++)
    {
        tmp=tmp*m%mod;
        if(calc(1,i)==calc(n-i+1,n)) ans=(ans+tmp)%mod;
    }
    printf("%lld\n",ans);
}

int main()
{
    freopen("x.in","r",stdin);
    freopen("x.out","w",stdout);
    int _;
    init();
    scanf("%d",&_);
    while(_--)
    {
        memset(sum1,0,sizeof(sum1));
        memset(sum2,0,sizeof(sum2));
        scanf("%d%d",&m,&n);
        for(int i=1;i<=n;i++) scanf("%d",&b[i]);
        for(int i=1;i<=n;i++)
            sum1[i]=(sum1[i-1]*base+b[i]%mod1)%mod1,
            sum2[i]=(sum2[i-1]*base+b[i]%mod2)%mod2;
        solve();
    }
}
posted @   彬彬冰激凌  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
历史上的今天:
2023-10-30 2023NOIP A层联测20 T3 点餐
点击右上角即可分享
微信分享提示