jzoj6275-[NOIP提高组模拟1]小L的数列【矩阵乘法,欧拉定理】
正題
題目大意
有遞推式fi=∏j=1kfi?jbjf_{i}=\prod_{j=1}^kf_{i-j}^{b_j}fi?=j=1∏k?fi?jbj??
給出f1~kf_{1\sim k}f1~k?和b1~kb_{1\sim k}b1~k?
求fnf_nfn?
解題思路
首先這題的指數(shù)如此之大所以不能直接存,而指數(shù)又不能直接模所以我們要用歐拉定理
(b,p)=1(b,p)=1(b,p)=1
?ab≡ab%φ(p)(modp)\Rightarrow a^b\equiv a^{b\% \varphi(p)}(\rm mod\ p)?ab≡ab%φ(p)(mod?p)
因?yàn)?span id="ze8trgl8bvbq" class="katex--inline">ppp為質(zhì)數(shù)所以就是
?ab≡ab%(p?1)(modp)\Rightarrow a^b\equiv a^{b\% (p-1)}(\rm mod\ p)?ab≡ab%(p?1)(mod?p)
然后對于答案肯定能表示成∏j=1kfkcj\prod_{j=1}^kf_k^{c_j}j=1∏k?fkcj??
那么對于ccc我們就可以用矩陣乘法求了
然后我們用矩陣乘法,用矩陣GnG^nGn中(0,i)(0,i)(0,i)表示fnf_nfn?的cic_ici?。
然后用矩陣乘法快速冪直接計(jì)算出GnG^nGn即可。
時(shí)間復(fù)雜度:O(k3log?n+klog?p):O(k^3\log n+k\log p):O(k3logn+klogp)
codecodecode
#pragma GCC optimize(2) #include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const int K=201,p=998244353,phi=998244352; int n,k,answer,num[K],b[K]; struct matrix{ll a[K][K];bool flag[K][K]; }f,ans,c; matrix operator*(const matrix &a,const matrix &b) {memset(c.a,0,sizeof(c.a));for(register int i=0;i<k;i++)for(register int j=0;j<k;j++)for(register int K=0;K<k;K++)c.a[i][j]=(c.a[i][j]+a.a[i][K]*b.a[K][j])%phi;return c; } int ksm(int x,int b) {int ans=1;while(b){if(b&1) ans=(ll)ans*x%p;x=(ll)x*x%p;b>>=1;}return ans; } int main() {//freopen("seq.in","r",stdin);//freopen("seq.out","w",stdout);scanf("%d%d",&n,&k);for(int i=1;i<k;i++)f.a[i][i-1]=1;for(int i=0;i<k;i++){scanf("%d",&b[i]);f.a[0][i]=b[i];}for(int i=0;i<k;i++)scanf("%d",&num[i]);if(n<=k){printf("%d",num[n-1]);return 0;}ans=f;n=n-k-1;while(n){ if(n&1) ans=ans*f;f=f*f;n>>=1;}answer=1;for(int i=0;i<k;i++)answer=(ll)answer*ksm(num[k-i-1],ans.a[0][i])%p;printf("%d",answer); }總結(jié)
以上是生活随笔為你收集整理的jzoj6275-[NOIP提高组模拟1]小L的数列【矩阵乘法,欧拉定理】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jzoj6276-[Noip提高组模拟1
- 下一篇: 路由器怎么限制别人蹭网家里的路由器怎么限