Description
给定 \(n,k\) 求有多少排列满足其构成的 \(\rm DFA\) 最长能识别长度为 \(k-1\) 的 ><><
交替的字符串
\(n\le 10^{16},k\le 10^6\)
Solution
Alpha1022 的题解是非常清楚并且完全正确的,用的另类拉格朗日反演也没有非常匪夷所思的配凑,在这里点赞并对一些可能的阅读障碍解读!
设 \(f_{k}(n)\) 为答案,枚举最大值的位置 \(j\),设左边有最长 \(2r/2r+1\) 的交替序列,因为 \(n\) 作为最大值可以替代 \(2r+1\) 中的最后一个,那么可以得到下式
设
下述运算无特别说明,都将以 \(x\) 为主元,导数是偏导
我们发现:
这可以通过使用上面的递推式和比对系数来证明,同时根据定义有:
考察常数项发现 \([x^0]A_0(x,t)=1\),所以可以得到 \(A^2_0(x,t)-A_1^2(x,t)=1\),所以我们可以发现一组在 \(x\) 为主元的时候的乘法逆:
设 \(G=\frac{F}{1-t}\)(也就是在 \(x\) 为主元意义下的前缀和),\(\alpha=\sqrt{1-t^2},C=e^{C'}\)
倒数第三步使用了左右两边变元不一致的积分,这是因为左式可以视作 \(\alpha G\) 为变量的函数,这个函数和右边以 \(x\) 为变量的函数完全相同,原像相同做积分必然也相同
(这步积分是我在本题里面留下的疑惑,不知道这样子的理解是不是合理)
注意 \(A(x,0)=\sum_{i\ge 0}t^k\) 只在 \(x=0\) 的时候 \(\frac {0^{0}}{0!}=1\),那么带入到这个式子里面发现 \(C=\frac{1-\alpha}t\)
注意到 \([x^0]\) 的系数对于解决问题是没有任何帮助的,那么可以将其忽略再进行考察,继续进行一些和式变换
使用另类拉格朗日反演强行展开
关于拉格朗日反演
整个理论的根基在于分式域的多项式:对于常数项为 \(0\),一次项不为 \(0\) 的幂级数 \(F\),有
分类讨论 \(k\neq -1\) 时 两者合并为 \((\frac{1}{k+1}F^{k+1})'\) 整多项式没有 \(x^{-1}\) 系数,否则直接比对系数 \({\rm LHS}=[x^0]x\frac{F'(x)}{F(x)}=[x^0]\frac{F'(x)}{\frac{F(x)}{x}}=\frac{f_1}{f_1}=1\)
设 \(F(x),G(x)\) 为常数项为 \(0\),一次项不为 \(0\) 的幂级数,\(H(x)\) 为任一幂级数
证明考虑先对 \(F(G)\) 展开并求导,发现次数不是 \(G(x)\) 次数不是 \(n\) 的时候所有其它项不能对 \([x^{-1}]\) 造成贡献,单独提取出来就能得到所求了
扩展拉格朗日反演如下:
除了多了一个复合函数求导得到的 \(H'(x)\) 之外没有区别
另类拉格朗日反演的两种形式:
证明也是类似的
展开过程中最头疼的仍然是找到一对互为复合逆的函数,这里考虑【The Child and Binary Tree】一题中给出的二叉树方程
将原式推导至复合结构,也就是使用 \(F\) 将所有 \(x\) 替换掉,这里只出现了 \(t^2\),那么设 \(4x=t^2\):
使用另类拉反的再复合结构,设 \(H(x)=x^r(1-x)^{s-1}(1+x)^{-r-s+1},F,G\) 如上,套公式即可:
下面直接给出完全进行和式变换之后的得到的 \(G=\frac{F}{1-t}\),中间的没有除了二项式定理之外的特别技巧
发现 \(n=s,k=r+2u\),那么要求 \([x^nt^k]\),枚举 \(r\),如果得到下式即可完成本题
上式关于 \(\frac{k-r}2\) 的 \(\rm GF\) 形如
两边乘 \((1-x)(1+x)\) 之后比对 \([x^{t-1}]\) 即可得到递推式:
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;
}