反演
二项式反演
二项式定理
考虑归纳证明:显然 \(n=1\) 时,原式成立
\((a+b)^n=(a+b)^{n-1}(a+b)=(\sum_{i=0}^{n-1}\binom{n-1}{i}a^{n-i-1}b^i)(a+b)\)
\(=\sum_{i=0}^{n-1}\binom{n-1}{i}a^{n-i}b^i+\sum_{i=1}^{n}\binom{n-1}{i-1}a^{n-i}b^{i}\)
由 \(\binom{n}{m}=\binom{n-1}{m}+\binom{n-1}{m-1}\),得 \((a+b)^n=\sum_{i=0}^n\binom{n}{i}a^{n-i}b^i\)
推论
- \(\binom{n}{m}=\binom{n}{n-m}\),相当于补集与原集一一对应
- \(\binom{n}{m}=\frac{n}{m}\binom{n-1}{m-1}\),由定义推导
- \(\binom{n}{m}=\binom{n-1}{m}+\binom{n-1}{m-1}\),杨辉三角
- \(\sum_{i=0}^n\binom{n}{i}=2^n\),\((1+1)^n\)
- \(\sum_{i=0}^n\binom{n}{i}(-1)^i=[n=0]\),\((1-1)^n\)
- \(\sum_{k=0}^n\binom{x}{k}\binom{y}{n-k}=\binom{x+y}{n}\),\(x+y\) 选 \(n\) 等于 枚举 \(x\) 中选 \(k\),\(y\) 中选 \(n-k\)
- \(\sum_{i=0}^n\binom{n}{i}^2=\binom{2n}{n}\),\(6\) 式 \(x=y\) 的情况
- \(\sum_{i=0}^ni\binom{n}{i}=n2^{n-1}\),\(\sum_{i=0}^nn\binom{n}{i}=\sum_{i=0}^n(i+n-i)\binom{n}{i}=\sum_{i=0}^ni\binom{n}{i}+\sum_{i=0}^ni\binom{n}{n-i}\)
- \(\sum_{i=0}^ni^2\binom{n}{i}=n(n+1)2^{n-2}\)
\(f(x):=\sum_{i=0}^n\binom{n}{i}x^i=(1+x)^n\).
\(xf'(x)=\sum_{i=0}^ni\binom{n}{i}x^i\)
\(x(f'(x)+xf''(x))=\sum_{i=0}^ni^2\binom{n}{i}x^i\)
When \(x=1\),\(\sum_{i=0}^ni^2\binom{n}{i}=n(n+1)2^{n-2}\)
- \(\sum_{i=0}^n\binom{i}{m}=\binom{n+1}{m+1}\)
\(n=m\) 时,显然成立
\(\sum_{i=0}^n\binom{i}{n-k+1}=\binom{n+1}{n-k+2}\),\(\binom{i}{n-k+1}\frac{k-1}{n-k+1}=\binom{i}{n-k}\)
\(\sum_{i=0}^n\binom{i}{n-k}=\sum_{i=0}^n\binom{i}{n-k+1}\frac{k-1}{n-k+1}=\frac{k-1}{n-k+1}\binom{i}{n-k}=\binom{n+1}{n-k+1}\)
- \(\binom{n}{r}\binom{r}{k}=\binom{n}{k}\binom{n-k}{r-k}\)
- \(\sum_{i=0}^n\binom{n-i}{i}=F_{n+1}\),\(F\) 为斐波那契数列(\(F_0=F_1=1\))
反演
有数列 \(f_i\),\(g_i\) 满足 则有
\[g_x=\sum_{i=0}^{x}\binom{x}{i}{(-1)}^{x-i} \sum_{j=0}^{i}\binom{i}{j}g_j \]\[g_x=\sum_{j=0}^{x}g_j\sum_{i=j}^{x}\binom{i}{j}\binom{x}{i}{(-1)}^{x-i} \]\[g_x=\sum_{j=0}^{x}g_j\sum_{i=0}^{x-j}\binom{i}{j}\binom{x}{i}{(-1)}^{x-i} \]\[g_x=\sum_{j=0}^{x}g_j\binom{x}{j}\sum_{i=0}^{x-j}\binom{x-i}{j-i}{(-1)}^{x-i} \]\[g_x=\sum_{j=0}^{x}g_j\binom{x}{j}[x=j]=g_x \]
单位根反演
单位根与原根
- 单位根:\(w_n^k=cos(\frac{2k\pi}{n})+i·sin(\frac{2k\pi}{n})=e^{i·\frac{2k\pi}{n}}\)
- \(w_n^xw_n^y=x_n^{x+y}\),\((w_n^x)k=w_n^{xk}\),\(w_n^k=w_n^{k\bmod n}\),\(|w_n^k|=1\)
- 原根:\(w_n^k=g^{k\frac{p-1}{n}}\)
原理
- \([n\mid k]=\frac{1}{n}\sum_{i=0}^n w_n^{ik}\)
- 若 \(n\mid k\),则 \(w_n^{ik}=w_n^0=1\),则原式等于 \(1\)
- 若 \(n\nmid k\),则 \(\frac{w_n^{kn}-1}{w_n^k-1}\),由于分子为 \(0\),则原式等于 \(0\)
应用
- \(\sum_{k=0}^m[n|k]f_k = \sum_{k=0}^m\frac{1}{n}\sum_{i=0}^{n-1}w_n^{ik}f_k=\frac{1}{n}\sum_{i=0}^{n-1}f(w_n^i)\) 其中 \(f_i\) 为多项式系数,\(f(x)\) 为带入求值
- 上述转换的实质是将与 \(m\) 有关的式子,通过快速计算多项式总和,转化为与 \(n\) 有关的式子
[LOJ 6485] LJJ 学二项式定理
- 题目简述:给出 \(n, s , a_0 , a_1 , a_2 , a_3(n\le10^{18},other\le 10^8)\) 求 \(\left[ \sum_{i=0}^n \left( {n\choose i} \cdot s^{i} \cdot a_{i\bmod 4} \right) \right] \bmod 998244353\)
- \(=\sum_{j=0}^3\sum_{i=0}^n {n \choose i}·s^i·a_j·[4\mid i-j]\)
- \(=\frac{1}{4}\sum_{k=0}^{3}\sum_{j=0}^3\sum_{i=0}^n{n \choose i}s^ia_jw_4^{(i-j)k}\)
- \(=\frac{1}{4}\sum_{k=0}^{3}\sum_{j=0}^3a_jw_4^{-jk}\sum_{i=0}^n{n \choose i}s^iw_4^{ik}\)
- \(=\frac{1}{4}\sum_{k=0}^{3}\sum_{j=0}^3a_jw_4^{-jk}(sw_4^k+1)^n\)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll p=998244353;
constexpr ll ksm(ll a,ll b)
{
ll ans=1;
for(;b;b>>=1,a=a*a%p)
if(b&1)ans=ans*a%p;
return ans;
}
const ll inv4=ksm(4,p-2),w[4]={1,ksm(3,(p-1)/4),ksm(3,(p-1)/2),ksm(3,(p-1)/4*3)};
int main()
{
int T;cin>>T;
while(T--)
{
ll n,s,a,ans=0;cin>>n>>s;
for(int j=0;j<4;j++)
{
cin>>a;
for(int k=0;k<4;k++)
ans+=a*w[((-j*k)%4+4)%4]%p*ksm((s*w[k]+1)%p,n%(p-1))%p;
}
cout<<ans%p*inv4%p<<'\n';
}
return 0;
}
BZOJ 3328 PYXFIB
- 题目简述:给出 \(n,p,k(n\le 10^{18},k\le 2\times 10^4,p\le 10^9)\) 求 \([\sum_{i=0}^{\lfloor\frac{n}{k}\rfloor}{n \choose ik}F_{ik}]\bmod p\)
- \(F_0=F_1=1\),\(F_i=F_{i-1}+F_{i-2}\),保证 \(k\mid p-1\)
- \(=\sum_{t=0}^nF_t{n\choose t}[k\mid t]\)
- \(=\frac{1}{k}\sum_{t=0}^n\sum_{i=0}^{k-1}w_k^{it}F_t{n\choose t}\),与二项式定理只差 \(F_t\) 不是 \(F^t\)
- 于是设矩阵 \(F\) 使得 \(F^t_{0,0}\) 为第斐波那契数列的第 \(t\) 项
- \(\frac{1}{k}\sum_{i=0}^{k-1}(w_k^iF+I)^n\),\(I\) 为单位矩阵
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
long long n,k,p;
struct Mat
{
ll a[2][2];int n,m;
Mat(int _n)
{
n=_n,m=_n;a[1][0]=a[0][1]=0;
for(int i=0;i<n;i++)
a[i][i]=1;
}
Mat(int _n,int _m){memset(a,0,sizeof a);n=_n;m=_m;}
ll* operator[](const int id){return a[id];}
Mat friend operator+ (Mat a,Mat b)
{
Mat ans(max(a.n,b.n),max(a.m,b.m));
for(int i=0;i<ans.n;i++)
for(int j=0;j<ans.m;j++)
ans[i][j]=(a[i][j]+b[i][j])%p;
return ans;
}
Mat friend operator* (Mat a,Mat b)
{
Mat ans(a.n,b.m);
for(int i=0;i<ans.n;i++)
for(int j=0;j<ans.m;j++)
for(int k=0;k<ans.m;k++)
ans[i][j]=(ans[i][j]+a[i][k]*b[k][j])%p;
return ans;
}
Mat friend operator* (Mat a,const ll b)
{
for(int i=0;i<a.n;i++)
for(int j=0;j<a.m;j++)
a[i][j]=(a[i][j]*b)%p;
return a;
}
};
ll ksm(ll a,ll b)
{
ll ans=1;
for(;b;b>>=1,a=a*a%p)
if(b&1)ans=ans*a%p;
return ans;
}
Mat ksm(Mat a,ll b)
{
Mat ans(max(a.n,a.m));
for(;b;b>>=1,a=a*a)
if(b&1)ans=ans*a;
return ans;
}
bool GetG(ll g){ll q=p-1;for(ll i=2;i*i<=q;i++)if(q%i==0&&(ksm(g,i)==1||ksm(g,q/i)==1))return false;return true;}
int GetG(){for(ll i=2;;i++)if(GetG(i))return i;}
int main()
{
int T;cin>>T;
while(T--)
{
cin>>n>>k>>p;
ll invk=ksm(k,p-2),g=GetG(),w1=ksm(g,(p-1)/k),w=1;
Mat ans(1,2);
for(int i=0;i<k;i++)
{
Mat F(2,2),A(1,2);
A[0][0]=1;A[0][1]=1;
F[0][0]=0;F[0][1]=1;
F[1][0]=1;F[1][1]=1;
F=ksm(F*w+Mat(2),n);
w=w*w1%p;A=A*F;
ans=ans+A;
}
cout<<ans[0][0]%p*invk%p<<'\n';
}
return 0;
}
#6358. 前夕
- 考虑容斥,设 \(f_x\) 表示,选了至少 \(m\) 种力量的方案数,设恰好为 \(m\) 种力量的方案数为 \(g_x\)
- \(f_x=\binom{n}{x}({2}^{2^{n-x}}-1)\),\(f_x=\sum_{i=x}^n\binom{i}{x}\)
- 由二项式反演 \(g_x=\sum_{i=x}^n\binom{i}{x}f_i(-1)^{i-x}\),\(ans=\sum_{x=0}^n\sum_{i=x}^n\binom{i}{x}f_i[4|x](-1)^{i-x}\)
- 由单位根反演 \(ans=\sum_{x=0}^n\sum_{i=x}^n\binom{i}{x}f_i\frac{1}{4}\sum_{j=0}^3w_{4}^{xj}(-1)^{i-x}\)
- \(ans=\frac{1}{4}\sum_{i=0}^nf_i\sum_{j=0}^3\sum_{x=0}^i\binom{i}{x}{w_{4}^{j}}^x(-1)^{i-x}\)
- \(ans=\frac{1}{4}\sum_{i=0}^n\binom{n}{i}({2}^{2^{n-i}}-1)\sum_{j=0}^3(w_{4}^{j}-1)^i\)
#include <bits/stdc++.h>
using namespace std;
typedef long long var;
const var p=998244353;
var ksm(var a,var b){var ans=1;for(;b;b>>=1,a=a*a%p)if(b&1)ans=ans*a%p;return ans;}
bool GetG(var g){var q=p-1;for(var i=2;i*i<=q;i++)if(q%i==0&&(ksm(g,i)==1||ksm(g,q/i)==1))return false;return true;}
int GetG(){for(var i=2;;i++)if(GetG(i))return i;}
const int N=10000100;
int A[N],V[N],S[N],T[4],W[4];
int main()
{
var g=GetG(),n; cin>>n;
S[0]=2;for(int i=1;i<N;i++)S[i]=1ll*S[i-1]*S[i-1]%p;
A[0]=1;for(int i=1;i<N;i++)A[i]=1ll*A[i-1]*i%p;
V[N-1]=ksm(A[N-1],p-2);for(int i=N-2;i>=0;i--)V[i]=1ll*V[i+1]*(i+1)%p;
auto C=[=](var n,var m){return 1ll*A[n]*V[m]%p*V[n-m]%p;};
var ans=0;
for(int j=0;j<=3;j++)T[j]=1;
for(int j=0;j<=3;j++)W[j]=ksm(g,(p-1)/4*j);
for(int i=0;i<=n;i++)
{
var ss=0;for(int j=0;j<=3;j++)ss+=T[j];ss%=p;
ans=(ans+1ll*C(n,i)*(S[n-i]-1)%p*ss)%p;
for(int j=0;j<=3;j++)T[j]=1ll*T[j]*(W[j]-1)%p;
}
cout<<(ans*ksm(4,p-2)%p+1+p)%p<<endl;
return 0;
}

浙公网安备 33010602011771号