,求出最小的满足,不存在输出。
有原式可知未知。
将用原根表示,从而将乘法变成加法,的原根是,则,可得
观察可知,的意义同上。
这个式子显然能带入快速幂,快速幂主要是求解出的系数,所以将式子带入后就能求出。
所以现在问题就变成了求解已知,直接上模板。
code:
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int mod=998244353,_mod=mod-1,maxn=(1<<16)-1; int gcd(int a,int b) { if(!b) return a; while((a%=b) && (b%=a)); return a+b; } int qpow(ll a,ll b,int mod) { ll res=1; while(b) { if(b&1) res=res*a%mod; a=a*a%mod; b>>=1; } return res; } int n,K,m; struct node{ ll mt[105][105]; node operator*(const node&a) const{ node res; for(int i=0;i<K;++i) for(int j=0;j<K;++j) { res.mt[i][j]=0;//不加有时会出错 for(int k=0;k<K;++k) res.mt[i][j]=(res.mt[i][j]+mt[i][k]*a.mt[k][j])%_mod; } return res; } }res,base; struct HASH{ int v[maxn+1],tot,ed=0; struct node{ int t,p,next; }a[maxn<<1]; void ins(int x,int y) { int k=x&maxn; if(v[k]!=ed) { v[k]=ed; a[k].t=x,a[k].p=y,a[k].next=0; } else { for(;;k=a[k].next) { if(a[k].t==x) return a[k].p=y,void(); if(!a[k].next) break; } a[k].next=++tot,a[tot].t=x,a[tot].p=y,a[tot].next=0; } } int find(int x) { int k=x&maxn; if(v[k]!=ed) return -1; for(;;k=a[k].next) if(a[k].t==x) return a[k].p; else if(!a[k].next) return -1; } }mp; int bsgs(int g,int b,int p,int k) { if(b==1) return 0; int m=ceil(sqrt(p)); mp.tot=maxn; ll tmp=1,s=1,x=qpow(g,k%(p-1),p); for(int j=0; j<m; ++j) mp.ins(tmp*b%p,j),tmp=tmp*x%p; for(int i=1; i<=m; ++i) { s=s*tmp%p; if(~mp.find(s)) return i*m-mp.find(s); } return -1; } int solve(int p,int k,int a) { if(a==0) return 0; int g=3; int res=bsgs(g,a,p,k); if(res==-1) return -1; int delta=(p-1)/gcd(k,p-1); return qpow(g,res%delta,p); } signed main() { cin.sync_with_stdio(false), cin.tie(nullptr),cout.tie(nullptr); cin>>K; for(int i=0;i<K;++i) cin>>base.mt[i][0]; for(int i=1;i<K;++i) base.mt[i-1][i]=1; res.mt[0][0]=1; cin>>n>>m; if(m==1) return cout<<"1\n",0; n-=K; mp.ed=1; while(n) { if(n&1) res=res*base; base=base*base; n>>=1; } cout<<solve(mod,res.mt[0][0],m)<<'\n'; return 0; }