,求出最小的
满足
,不存在输出
。
有原式可知未知。
将用原根表示,从而将乘法变成加法,
的原根是
,则
,可得
观察可知,
的意义同上。
这个式子显然能带入快速幂,快速幂主要是求解出的系数,所以将式子带入后就能求出
。
所以现在问题就变成了求解已知,直接上
模板。
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;
}

京公网安备 11010502036488号