日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【BZOJ3328】PYXFIB【矩阵快速幂】【单位根反演】【二项式定理】

發(fā)布時(shí)間:2023/12/3 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【BZOJ3328】PYXFIB【矩阵快速幂】【单位根反演】【二项式定理】 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

傳送門

題意:

∑i=0?nk?(nik)Fik\sum_{i=0}^{\lfloor\frac nk\rfloor}\binom n{ik}F_{ik}i=0?kn???(ikn?)Fik?

FFF為斐波拉契數(shù)列

n≤1e18,k≤2e4,p≤1e9n\leq 1e18,k\leq2e4,p\leq1e9n1e18,k2e4,p1e9且為質(zhì)數(shù)且模kkk111


顯然就是求

∑i=0n[k∣i](ni)Fi\sum_{i=0}^n[k\mid i]\binom niF_ii=0n?[ki](in?)Fi?

顯然FFF可以通過矩陣表示出來

設(shè)

A=(1110),S=(10)A=\left(\begin{matrix}1&1\\1&0\end{matrix}\right),S=\left(\begin{matrix}1\\0\end{matrix}\right)A=(11?10?),S=(10?)

那么只需要求出

∑i=0n[k∣i](ni)AiS\sum_{i=0}^n[k\mid i]\binom niA^iSi=0n?[ki](in?)AiS

相當(dāng)于求

∑i=0n[k∣i](ni)Ai\sum_{i=0}^n[k\mid i]\binom niA^ii=0n?[ki](in?)Ai

然后日常把這個(gè)幻視成二項(xiàng)式定理害得我調(diào)了兩個(gè)小時(shí)

顯然可以單位根反演

1k∑j=0k?1∑i=0n(ni)Aiωij\frac 1k\sum_{j=0}^{k-1}\sum_{i=0}^n\binom niA^i\omega^{ij}k1?j=0k?1?i=0n?(in?)Aiωij

=1k∑j=0k?1∑i=0n(ni)(Aωj)i=\frac 1k\sum_{j=0}^{k-1}\sum_{i=0}^n\binom ni(A\omega^j)^i=k1?j=0k?1?i=0n?(in?)(Aωj)i

二項(xiàng)式定理走一波

=1k∑j=0k?1(Aωj+I)n=\frac 1k\sum_{j=0}^{k-1}(A\omega^j+I)^n=k1?j=0k?1?(Aωj+I)n

然后就可以算了

因?yàn)?span id="ozvdkddzhkzd" class="katex--inline">p%k=1p\%k=1p%k=1,所以可以找一個(gè)原根算出ω\omegaω

復(fù)雜度O(klog?n)O(k\log n)O(klogn)

#include <iostream> #include <cstdio> #include <cstring> #include <cctype> using namespace std; typedef long long ll; ll n; int k,MOD; inline int add(const int& x,const int& y){return x+y>=MOD? x+y-MOD:x+y;} inline int dec(const int& x,const int& y){return x<y? x-y+MOD:x-y;} inline int qpow(int a,int b) {int ans=1;while (b){if (b&1) ans=(ll)ans*a%MOD;a=(ll)a*a%MOD;b>>=1;}return ans; } int g,Wn; inline bool check(int x) {int n=x;for (int i=2;i*i<=x;i++)if (x%i==0){if (qpow(g,n/i)==1) return false;while (x%i==0) x/=i;}if (x>1&&qpow(g,n/x)==1) return false;return true; } struct mat {int e[2][2];mat(const int& x=0){e[0][0]=e[1][1]=x;e[0][1]=e[1][0]=0;}int* operator [](int i){return e[i];} }; inline int det(mat m){return dec((ll)m[0][0]*m[1][1]%MOD,(ll)m[0][1]*m[1][0]%MOD);} inline mat operator *(mat a,mat b) {mat ans;ans[0][0]=add((ll)a[0][0]*b[0][0]%MOD,(ll)a[0][1]*b[1][0]%MOD);ans[0][1]=add((ll)a[0][0]*b[0][1]%MOD,(ll)a[0][1]*b[1][1]%MOD);ans[1][0]=add((ll)a[1][0]*b[0][0]%MOD,(ll)a[1][1]*b[1][0]%MOD);ans[1][1]=add((ll)a[1][0]*b[0][1]%MOD,(ll)a[1][1]*b[1][1]%MOD); return ans; } inline mat operator +(mat a,mat b) {mat ans;ans[0][0]=add(a[0][0],b[0][0]);ans[0][1]=add(a[0][1],b[0][1]);ans[1][0]=add(a[1][0],b[1][0]);ans[1][1]=add(a[1][1],b[1][1]); return ans; } inline mat operator *(mat a,const int& t) {mat ans;ans[0][0]=(ll)a[0][0]*t%MOD;ans[0][1]=(ll)a[0][1]*t%MOD;ans[1][0]=(ll)a[1][0]*t%MOD;ans[1][1]=(ll)a[1][1]*t%MOD; return ans; } inline mat qpow(mat a,ll p) {mat ans(1);while (p){if (p&1) ans=ans*a;a=a*a;p>>=1;}return ans; } int main() {int T;scanf("%d",&T);while (T--){scanf("%lld%d%d",&n,&k,&MOD);for(g=2;!check(MOD-1);g++);Wn=qpow(g,(MOD-1)/k);mat T,sum;T[0][0]=T[0][1]=T[1][0]=1;T[1][1]=0;for (int i=0;i<k;i++,T=T*Wn) sum=sum+qpow(T+mat(1),n);sum=sum*qpow(k,MOD-2);printf("%d\n",sum[0][0]);}return 0; } 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的【BZOJ3328】PYXFIB【矩阵快速幂】【单位根反演】【二项式定理】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。