"蔚来杯"2022牛客暑期多校训练营2 E Falfa with Substring

赛时做出来了。

考虑能求出 f[i][j]=f[i3][j1]+f[i1][j],j[1,n],也就是说在 n 个空选 j 个 bit,转为有 n2 个空,选 j 个空,每个空之间至少间隔 2 个空(选左端点)。

oeis 一下,发现就是经典多次前缀和结论,(1+x1+x2...)a 可以认为从 (1,0) 游走到 (a,b) 的方案数,也就是源点有无限 1,向外散。

然后就是其他随便选,二项式反演,NTT。

后面套路讲解

#include <bits/stdc++.h> #define int long long #define pb push_back using namespace std; int rd() { int f=1,sum=0; char ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) {sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();} return sum*f; } const int N=(int)(6e6+5),M=N,mod=998244353,G=3; int fpow(int x,int y) { int res=1; while(y) { if(y&1) res=res*x%mod; y>>=1; x=x*x%mod; } return res; } const int invG=fpow(G,mod-2); void NTT(int *f,int n,bool fl=1) { static int tr[M]; for(int i=0;i<n;i++) tr[i]=(tr[i>>1]>>1)|((i&1)?(n>>1):0); for(int i=0;i<n;i++) if(i<tr[i]) swap(f[i],f[tr[i]]); for(int p=2;p<=n;p<<=1) { int len=(p>>1),w=fpow(fl?G:invG,(mod-1)/p); for(int l=0;l<n;l+=p) { int buf=1; for(int i=l;i<l+len;i++) { int qwq=f[i+len]*buf%mod; f[i+len]=(f[i]-qwq)%mod; f[i]=(f[i]+qwq)%mod; buf=buf*w%mod; } } } if(fl) return ; int qwq=fpow(n,mod-2); for(int i=0;i<n;i++) f[i]=f[i]*qwq%mod; } int f[M],g[M],jie[N],djie[N],n; int C(int n,int m) { if(m>n||n<0||m<0) return 0; return jie[n]*djie[m]%mod*djie[n-m]%mod; } inline int get(int a,int b) { return C(a+b-1,b); // (1,0) (a,b) } void solve() { // memset(f,0,sizeof(f)); memset(g,0,sizeof(g)); n=rd(); if(n==1) { printf("26 0"); return ; } n-=2; f[0]=fpow(26,n+2); for(int i=1;i<=n;i++) { int qwq=(i-1)*3+1,num=n+2-i*3; if(num<0) break ; int res=get(i+1,n-qwq); f[i]=res*fpow(26,num)%mod; } // 太屑了 不放 n^3 ,你玩nmd,是个紫就要 NTT 做差卷积?? // 老子今天都不知道写几遍 NTT 了 for(int i=0;i<=n;i++) f[i]=jie[i]*f[i]%mod; for(int i=0;i<=n;i++) g[i]=((i&1)?-1:1)*djie[i]%mod; reverse(f,f+1+n); int m; for(m=1;m<n+n+2;m<<=1); NTT(f,m,1); NTT(g,m,1); for(int i=0;i<m;i++) f[i]=f[i]*g[i]%mod; NTT(f,m,0); reverse(f,f+1+n); for(int i=0;i<=n;i++) { int qwq=f[i]*djie[i]%mod; qwq=(qwq%mod+mod)%mod; printf("%lld ",qwq); } printf("0 0"); } signed main() { jie[0]=1; for(int i=1;i<=N-5;i++) jie[i]=jie[i-1]*i%mod; djie[N-5]=fpow(jie[N-5],mod-2); for(int i=N-5;i;i--) djie[i-1]=djie[i]*i%mod; solve(); return 0; }

__EOF__

本文作者F x o r G
本文链接https://www.cnblogs.com/xugangfan/p/16513527.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   FxorG  阅读(55)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示