Description
给定 n,k 求有多少排列满足其构成的 DFA 最长能识别长度为 k−1 的 ><><
交替的字符串
n≤1016,k≤106
Solution
Alpha1022 的题解是非常清楚并且完全正确的,用的另类拉格朗日反演也没有非常匪夷所思的配凑,在这里点赞并对一些可能的阅读障碍解读!
设 fk(n) 为答案,枚举最大值的位置 j,设左边有最长 2r/2r+1 的交替序列,因为 n 作为最大值可以替代 2r+1 中的最后一个,那么可以得到下式
fk(n)=n∑i=1(n−1i−1)∑2r+s=k−1(f2r(j−1)+f2r+1(j−1))fs(n−i)
设
A(x,t)=∑fk(n)xnn!tkA0(x,t)=A(x,t)+A(x,−t)2A1(x,t)=A(x,t)−A(x,−t)2
下述运算无特别说明,都将以 x 为主元,导数是偏导
我们发现:
∂A(x,t)∂x=(tA0(x,t)+A1(x,t))A(x,t)
这可以通过使用上面的递推式和比对系数来证明,同时根据定义有:
∂(A20(x,t)−A21(x,t))∂x=A′(x,t)A(x,−t)+A(x,t)A′(x,−t)=0
考察常数项发现 [x0]A0(x,t)=1,所以可以得到 A20(x,t)−A21(x,t)=1,所以我们可以发现一组在 x 为主元的时候的乘法逆:
A(x,t)A(x,−t)=1
设 G=F1−t(也就是在 x 为主元意义下的前缀和),α=√1−t2,C=eC′
∂A(x,t)∂x=(tA0(x,t)+A1(x,t))A(x,t)∂A(x,t)∂x=12((t+1)A+(t−1)A−1)A∂A(t+1)A2+(t−1)=∂x2∂G(1−t2)G2−1=∂x2[1αG−1−1αG+1]∂(αG)=α∂xln(αG−1αG+1)=αx+C′αG−1αG+1=C×eαxG(x)=2α(11−eαxC−1)
倒数第三步使用了左右两边变元不一致的积分,这是因为左式可以视作 αG 为变量的函数,这个函数和右边以 x 为变量的函数完全相同,原像相同做积分必然也相同
(这步积分是我在本题里面留下的疑惑,不知道这样子的理解是不是合理)
注意 A(x,0)=∑i≥0tk 只在 x=0 的时候 000!=1,那么带入到这个式子里面发现 C=1−αt
注意到 [x0] 的系数对于解决问题是没有任何帮助的,那么可以将其忽略再进行考察,继续进行一些和式变换
G(x)−[x0]G=2α11−eαx1−αt=2α∑i≥0(eαx1−αt)i=2α∑r≥0t−r(1−α)r∑s≥0(rαx)ss!
使用另类拉格朗日反演强行展开
(1−√1−t2)r(1−t2)s−12
关于拉格朗日反演
整个理论的根基在于分式域的多项式:对于常数项为 0,一次项不为 0 的幂级数 F,有
[x−1]Fk(x)F′(x)=[k=−1]
分类讨论 k≠−1 时 两者合并为 (1k+1Fk+1)′ 整多项式没有 x−1 系数,否则直接比对系数 LHS=[x0]xF′(x)F(x)=[x0]F′(x)F(x)x=f1f1=1
设 F(x),G(x) 为常数项为 0,一次项不为 0 的幂级数,H(x) 为任一幂级数
[xn]F(x)=1n[xn−1](xG(x))n
证明考虑先对 F(G) 展开并求导,发现次数不是 G(x) 次数不是 n 的时候所有其它项不能对 [x−1] 造成贡献,单独提取出来就能得到所求了
扩展拉格朗日反演如下:
[xn]H(F(x))=1n[xn−1]H′(x)(xG(x))n
除了多了一个复合函数求导得到的 H′(x) 之外没有区别
另类拉格朗日反演的两种形式:
[xn]Fk(x)=[x−k−1]G′(x)G−n−1
∑i≥0([xi]Fk)Gi(x)=xk∑i≥0([xi]Fk)Gi−n(x)G′(x)=G′(x)G−n(x)xk[x−1]∑i≥0([xi]Fk)Gi−n(x)G′(x)=[x−k−1]G′(x)G−n(x)[xn]Fk=[x−k−1]G′(x)G−n(x)
[xn]H(F(x))=[x−1]H(x)G′(x)G−n−1
证明也是类似的
展开过程中最头疼的仍然是找到一对互为复合逆的函数,这里考虑【The Child and Binary Tree】一题中给出的二叉树方程
F=x(1+F)2,G(x)=x(1+x)2→F(G(x))=x
将原式推导至复合结构,也就是使用 F 将所有 x 替换掉,这里只出现了 t2,那么设 4x=t2:
(1−√1−t2)r(1−t2)s−12=(1−√1−4x)r(√1−4x)s−1=2rFr(1−F)s−1(1+F)−r−s+1
使用另类拉反的再复合结构,设 H(x)=xr(1−x)s−1(1+x)−r−s+1,F,G 如上,套公式即可:
Fr(1−F)s−1(1+F)−r−s+1=[xn]H(x)G′(x)(xG(x))n+1=[xn]xr(1+x)s−1(1+x)−r−s+11−x(1+x)3(1+x)2(n+1)
下面直接给出完全进行和式变换之后的得到的 G=F1−t,中间的没有除了二项式定理之外的特别技巧
G(x)−[x0]G(x)=∑r,u21−r−2ut2u+r∑s≥0(rx)ss!∑i≥0(−1)i(si)(r+2u−su−i)
发现 n=s,k=r+2u,那么要求 [xntk],枚举 r,如果得到下式即可完成本题
∑i(−1)i(ni)(k−nk−r2−i)
上式关于 k−r2 的 GF 形如
ˆF=(1+x)n(1−x)k−n→ˆF′=−sF1+x−nF1−x
两边乘 (1−x)(1+x) 之后比对 [xt−1] 即可得到递推式:
ft=−(n+s)ft−1+(s−n+t−2)ft−2
Code
const int N=1e6+10;
int n,k,cnt;
int pri[N],pw[N];
bool fl[N];
int f[N],inv[N];
inline int G(int n,int k){
int sum=0,s=(n-k)%mod;
f[0]=1;
for(int t=1;t<=k;++t){
f[t]=0;
ckdel(f[t],mul((n+s)%mod,f[t-1]));
ckadd(f[t],mul((s+mod-n%mod+t-2)%mod,f[t-2]));
f[t]=(f[t]%mod+mod)%mod;
ckmul(f[t],inv[t]);
}
for(int r=k;r>=0;r-=2) ckadd(sum,mul(pw[r],f[(k-r)/2]));
if(k<1) ckmul(sum,2);
if(k>1) ckmul(sum,ksm(inv[2],k-1));
return sum;
}
signed main(){
freopen("fafa.in","r",stdin); freopen("fafa.out","w",stdout);
n=read(); k=read(); pw[1]=1;
inv[0]=inv[1]=1; for(int i=2;i<=k;++i) inv[i]=mod-mul(mod/i,inv[mod%i]);
for(int i=2;i<=k;++i){
if(!fl[i]) pri[++cnt]=i,pw[i]=ksm(i,n%(mod-1));
for(int j=1;j<=cnt&&pri[j]*i<=k;++j){
fl[i*pri[j]]=1;
pw[i*pri[j]]=mul(pw[i],pw[pri[j]]);
if(i%pri[j]==0) break;
}
}
print(del(G(n,k),G(n,k-1)));
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律