正题
题目大意
有递推式fi=∏j=1kfi−jbjf_{i}=\prod_{j=1}^kf_{i-j}^{b_j}fi=j=1∏kfi−jbj
给出f1∼kf_{1\sim k}f1∼k和b1∼kb_{1\sim k}b1∼k
求fnf_nfn
解题思路
首先这题的指数如此之大所以不能直接存,而指数又不能直接模所以我们要用欧拉定理
(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)
因为ppp为质数所以就是
⇒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∏kfkcj
那么对于ccc我们就可以用矩阵乘法求了
然后我们用矩阵乘法,用矩阵GnG^nGn中(0,i)(0,i)(0,i)表示fnf_nfn的cic_ici。
然后用矩阵乘法快速幂直接计算出GnG^nGn即可。
时间复杂度:O(k3logn+klogp):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);
}