CF1106F Lunar New Year and a Recursive Sequence
。。。。
几个比较重要的数论知识
对于m的原根g,满足$g^i (mod\ p)(0<=i<=p-2)$与$1$到$p-1$一一对应
发现$k$项之后的$f$都是$f_k$的幂次
幂次的加法用矩阵快速幂得到x
即$f_k^{x}=m(mod\ 998244353)$
998244353的原根为3
将柿子化成 $3^{s*x}=m(mod\ 998244353)$
$s*x$可以通过$bsgs$得到
然后求x的逆元
得到$s$,$3^{s}$即为答案
1 #include <bits/stdc++.h>
2 using namespace std;
3
4 #define LL long long
5 const LL mod=998244353;
6
7 int k,b[110];
8 int n,m;
9
10 struct Matrix{
11 int jz[110][110];
12 Matrix(int x=0){
13 for(int i=1;i<=k;++i)
14 for(int j=1;j<=k;++j)
15 jz[i][j]=0;
16 for(int i=1;i<=k;++i)jz[i][i]=x;
17 }
18 Matrix operator* (Matrix a){
19 Matrix c;
20 for(int s=1;s<=k;++s)for(int i=1;i<=k;++i)for(int j=1;j<=k;++j)
21 c.jz[i][j]=(c.jz[i][j]+1LL*(this->jz[i][s])*a.jz[s][j]%(mod-1))%(mod-1);
22 return c;
23 }
24 inline void pt(){
25 for(int i=1;i<=k;++i,puts(""))
26 for(int j=1;j<=k;++j)
27 cout<<jz[i][j]<<" ";
28 return ;
29 }
30 };
31
32 inline LL qpow(LL a,LL b){
33 LL res=1;a%=mod;
34 for(;b;b>>=1,a=a*a%mod)
35 if(b&1)res=res*a%mod;
36 return res%mod;
37 }
38
39 LL BSGS(LL y,LL z,LL p){
40 z%=p;
41 LL x=sqrt(p)+1;
42 unordered_map<LL ,int >hsh;
43 LL mi=1;
44 for(LL i=0;i<x;++i,mi=mi*y%mod)hsh[z*mi%mod]=i+1;
45 for(LL i=1,Mi=mi;i<=x+1;++i,Mi=Mi*mi%mod){
46 int b=hsh[Mi];
47 if(b)return 1LL*i*x-(b-1);
48 }
49 return -1;
50 }
51
52 LL exgcd(LL a,LL b,LL &x,LL &y){
53 if(!b){
54 x=1;y=0;
55 return a;
56 }
57 LL d=exgcd(b,a%b,x,y);
58 LL tmp=x;
59 x=y;
60 y=tmp-a/b*y;
61 return d;
62 }
63
64 int main(){
65 scanf("%d",&k);
66 for(int i=1;i<=k;++i)scanf("%d",&b[i]);
67 scanf("%d%d",&n,&m);
68
69 Matrix A;
70 for(int i=1;i<=k;++i)A.jz[i][k]=b[k-i+1];
71 for(int i=2;i<=k;++i)A.jz[i][i-1]=1;
72 int num=n-k;
73 Matrix ans(1);
74 for(;num;num>>=1,A=A*A)
75 if(num&1)ans=ans*A;
76
77 LL x=ans.jz[k][k];
78 LL sx=BSGS(3,m,mod);
79 if(sx==-1){
80 puts("-1");
81 return 0;
82 }
83
84 // cout<<qpow(3,sx)<<endl;
85 // cout<<x<<" "<<sx<<endl;
86
87 LL X,Y;
88 LL d=exgcd(x,mod-1,X,Y);
89 if(sx%d){
90 puts("-1");
91 return 0;
92 }
93 // cout<<X<<" "<<x<<endl;
94 // cout<<X*x%(mod-1)<<endl;
95 LL s=(sx/d*X%(mod-1)+(mod-1))%(mod-1);
96 // cout<<X<<" "<<s<<endl;
97 printf("%lld\n",qpow(3,s));
98 return 0;
99 }