XX Open Cup GP of Gomel B (Baekjoon18743) Bin【生成函数+分治fft】
发布日期:2021-05-06 15:54:57 浏览次数:28 分类:精选文章

本文共 1536 字,大约阅读时间需要 5 分钟。

f ( n ) f(n) f(n) 表示叶子节点为 n n n 的方案数。则根据定义:

f ( n ) = ∑ i ≤ n − i + k f ( i ) × f ( n − i ) f(n)=\sum_{i\le n-i+k}f(i)\times f(n-i) f(n)=ini+kf(i)×f(ni)
可以发现因为 k k k 很小,所以 i i i 是枚举了 1 1 1 n n n 的一半多一点点的位置。

如果让 i i i 枚举 1 1 1 n n n ,新的和就变成了 f ( n ) f(n) f(n) 的两倍少中间那一点的样子。

于是考虑两边同时 × 2 \times 2 ×2 把限制放松

2 f ( n ) = ∑ 1 ≤ i < n f ( i ) × f ( n − i ) + ∑ ∣ i − ( n − i ) ∣ ≤ k f ( i ) f ( n − i ) 2f(n)=\sum_{1\le i<n}f(i)\times f(n-i)+\sum_{|i-(n-i)|\le k}f(i)f(n-i) 2f(n)=1i<nf(i)×f(ni)+i(ni)kf(i)f(ni)
把它看成多项式,那就是卷积形式。

左边的和式就是分治fft可做,(注意是自己卷自己和分治fft的模板不太一样。 O ( n log ⁡ 2 n ) O(n\log^2n) O(nlog2n)

右边的和式在分治到单个节点的时候暴力算, O ( n k ) O(nk) O(nk)

时间复杂度 O ( n log ⁡ 2 n + n k ) O(n\log^2n+nk) O(nlog2n+nk)

#include 
#define N 2000006using namespace std;typedef long long ll; typedef vector
vec;const ll mod=998244353;int now_limit;int rev[N];ll wq[20][N],fac[N],inv[N];ll ksm(ll x,ll y){ ll res=1; while(y){ if(y&1)res=res*x%mod; x=x*x%mod; y>>=1; } return res;}void init_NTT(int limit){ if(limit==now_limit) return; now_limit=limit; int l=0; while((1<
>1]>>1)|((i&1)<<(l-1)); if(wq[0][0]==0){ while(limit<1000000) limit<<=1; for(int mid=1,l=0;mid
<<=1,l++){ wq[l][0]=1,wq[l][1]=ksm(3,(mod-1)/(mid<<1)); for(int k=2;k
k) for(int i=(l-k+1)/2;i+i
>1; cdq_NTT(l,mid); vec a,b; a=vector
(&f[l],&f[mid]); b=vector
(&f[0],&f[min(r-l,mid)]); int limit=1; while(limit
>n>>k; f.resize(n+1); f[1]=2; inv2=ksm(2,mod-2); cdq_NTT(0,n+1); cout<
<<'\n';}
上一篇:CF755G PolandBall and Many Other Balls【矩阵快速幂+多项式乘法】
下一篇:[AHOI2013]差异 【SAM后缀树+树形dp】

发表评论

最新留言

很好
[***.229.124.182]2025年03月25日 04时04分57秒