单位根反演[loj6485]LJJ 学二项式定理
前言
之前寫反演的博客對于單位根反演只提了FFT
這里補一下一個應用
單位根反演
fi=∑j=0n?1ωni?jgj?gi=∑j=0n?1ωn?i?jnfjf_i=\sum_{j=0}^{n-1}\omega_n^{i*j}g_j\Leftrightarrow g_i=\sum_{j=0}^{n-1}\frac{\omega_n^{-i*j}}nf_jfi?=j=0∑n?1?ωni?j?gj??gi?=j=0∑n?1?nωn?i?j??fj?
這是FFT里的
證明很方便,見我的博客對于容斥原理&反演的思考和總結
事實上,我們思考上式的本質
我們發現就是
[n∣x]=1n∑i=0n?1(ωnx)i[n|x]=\frac1n\sum_{i=0}^{n-1}(\omega_n^x)^i[n∣x]=n1?i=0∑n?1?(ωnx?)i
FFT中的形式把xxx取值a?ba-ba?b,又保證∣a?b∣<n|a-b|<n∣a?b∣<n那么n∣xn|xn∣x只有在a=ba=ba=b的時候滿足,即δa,b\delta_{a,b}δa,b?
所以根據這個我們可以得到更多的應用,常見形式如下
對一個多項式
f(x)=∑i=0n?1aixif(x)=\sum_{i=0}^{n-1}a_ix^if(x)=i=0∑n?1?ai?xi
求所有次數為kkk的倍數的系數之和
Ans=∑i=0n?1[k∣i]ai\begin{aligned} Ans&=\sum_{i=0}^{n-1}[k|i]a_i\\ \end{aligned}Ans?=i=0∑n?1?[k∣i]ai??
題解
題目要求的是
[∑i=0n((ni)?si?aimod4)]mod  998244353\left[\sum_{i=0}^n\left(\binom ni·s^i·a_{i\ mod\ 4}\right)\right]\mod998244353[i=0∑n?((in?)?si?ai?mod?4?)]mod998244353
我們對imod  4i\mod4imod4的值進行分別討論,我們現在要求的就是各組的系數和
我們現在要求
[∑i=0n((ni)?si[4∣i])]mod  998244353\left[\sum_{i=0}^n\left(\binom ni·s^i[4|i]\right)\right]\mod998244353[i=0∑n?((in?)?si[4∣i])]mod998244353
∑i=0n((ni)?si[4∣i])=∑i=0n((ni)?si14∑j=04?1(ω4i)j)=14∑j=03∑i=0n((ni)?si(ω4j)i)=14∑j=03(sω4j+1)n\begin{aligned} \sum_{i=0}^n\left(\binom ni·s^i[4|i]\right)&=\sum_{i=0}^n\left(\binom ni·s^i\frac14\sum_{j=0}^{4-1}(\omega_4^i)^j\right)\\ &=\frac14\sum_{j=0}^{3}\sum_{i=0}^n\left(\binom ni·s^i(\omega_4^j)^i\right)\\ &=\frac14\sum_{j=0}^{3}\left(s\omega_4^j+1\right)^n\\ \end{aligned}i=0∑n?((in?)?si[4∣i])?=i=0∑n?((in?)?si41?j=0∑4?1?(ω4i?)j)=41?j=0∑3?i=0∑n?((in?)?si(ω4j?)i)=41?j=0∑3?(sω4j?+1)n?
那么單個的系數就求得了,那么我們發現除了[4∣i][4|i][4∣i]的情況,還有[4∣i?1][4|i-1][4∣i?1],[4∣i?2][4|i-2][4∣i?2],[4∣i?3][4|i-3][4∣i?3]的情況,那么相當于是我們將關于x=ω4jx=\omega_4^jx=ω4j?的函數的值分別乘以x?1,x?2,x?3x^{-1},x^{-2},x^{-3}x?1,x?2,x?3,然后(具體做法是,對于x=ω4ix=\omega_4^ix=ω4i?,x?1=ω4?ix^{-1}=\omega_4^{-i}x?1=ω4?i?),其它的一樣做即可
代碼
#include<bits/stdc++.h> typedef long long ll; #define rg register template <typename T> inline void read(T&x){char cu=getchar();x=0;bool fla=0;while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}while(isdigit(cu))x=x*10+cu-'0',cu=getchar();if(fla)x=-x;} template <typename T> inline void printe(const T x){if(x>=10)printe(x/10);putchar(x%10+'0');} template <typename T> inline void print(const T x){if(x<0)putchar('-'),printe(-x);else printe(x);} const ll mod=998244353; ll T,n,s,a0,a1,a2,a3,w0,w1,w2,w3,inv; inline ll pow(ll x,ll y) {ll res=1;for(;y;y>>=1,x=x*x%mod)if(y&1)res=res*x%mod;return res; } int main() {read(T);w0=1,w1=pow(3,(mod-1)/4),w2=w1*w1%mod,w3=w1*w2%mod;inv=pow(4,mod-2);while(T--){read(n),read(s),read(a0),read(a1),read(a2),read(a3);const ll k0=pow(s*w0%mod+1,n),k1=pow(s*w1%mod+1,n),k2=pow(s*w2%mod+1,n),k3=pow(s*w3%mod+1,n);ll ans=0;ans=(ans+(k0*w0+k1*w0+k2*w0+k3*w0)%mod*a0)%mod;ans=(ans+(k0*w0+k1*w3+k2*w2+k3*w1)%mod*a1)%mod;ans=(ans+(k0*w0+k1*w2+k2*w0+k3*w2)%mod*a2)%mod;ans=(ans+(k0*w0+k1*w1+k2*w2+k3*w3)%mod*a3)%mod;print(ans*inv%mod),putchar('\n');}return 0; }總結
單位根反演需要推式子,但寫起來比較清真
總結
以上是生活随笔為你收集整理的单位根反演[loj6485]LJJ 学二项式定理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 模拟赛-20190228-随机数(ran
- 下一篇: Burnside引理和Polya定理学习