Loading

代码-CF1106F Lunar New Year and a Recursive Sequence

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define x first
#define y second
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
#define sz(a) int((a).size())
#define R(i,a,b) for(int i(a),i##E(b);i<i##E;i++)
#define L(i,a,b) for(int i((b)-1),i##E((a)-1);i>i##E;i--)
const int iinf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f;

//Data
const int N=100;
int n,p,q;

//Math
const int mod=998244353;
const int phi=998244352;
void fmod(int &x){x+=x>>31&mod;}
void fphi(int &x){x+=x>>31&phi;}
int gcd(int a,int b){return a?gcd(b%a,a):b;}
int Pow(int a,int x,int mod){
    int res=1; for(;x;x>>=1,a=1ll*a*a%mod)
    if(x&1) res=1ll*res*a%mod; return res;
}
int Phi(int x){
    int res=x;
    for(int d=2;d*d<=x;d++)if(x%d==0)
        {res=res/d*(d-1);while(x%d==0) x/=d;}
    if(x>1) res=res/x*(x-1);
    return res;
}
unordered_map<int,int> h;
int Log(int a,int b){
    // cout<<"a:"<<a<<" b:"<<b<<'\n';
    if(!a&&!(b%=mod)) return 0; if(!(a%=mod)) return -1;
    int sm=sqrt(mod)+1,u=1,v=1; h.clear(),h[b]=0;
    R(i,1,sm+1) h[1ll*b*(u=1ll*u*a%mod)%mod]=i;
    R(i,1,sm+1)if(h.count(v=1ll*v*u%mod)) return (i*sm-h[v])%phi;
    return -1;
}

//Matrix
struct Matrix{
    int arr[N][N];
    Matrix(){R(i,0,N)R(j,0,N) arr[i][j]=0;}
    int* operator[](int i){return arr[i];}
    Matrix operator*(Matrix b){
        Matrix res;
        R(k,0,n)R(i,0,n)R(j,0,n)
            fphi(res[i][j]+=1ll*arr[i][k]*b[k][j]%phi-phi);
        return res;
    }
    Matrix Pow(int x){
        Matrix res,a(*this); R(i,0,n) res[i][i]=1;
        for(;x;x>>=1,a=a*a)if(x&1) res=res*a;
        return res;
    }
};
Matrix ns,e;

//Main
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n;
    R(i,0,n) cin>>e[n-1-i][n-1];
    R(i,1,n) e[i][i-1]=1;
    cin>>p>>q,--p;
    ns[0][n-1]=1,ns=ns*e.Pow(p-(n-1));
    int x=ns[0][n-1],b=Log(3,q),g=gcd(phi,x);
    // cout<<x<<" "<<b<<'\n';
    if(!~b||b%g!=0) cout<<-1<<'\n',exit(0);
    int ph=phi/g;x/=g,b/=g;
    cout<<Pow(3,1ll*Pow(x,Phi(ph)-1,ph)*b%ph,mod)<<'\n';
    return 0;
}
/*

数据提示:矩阵快速幂?

暴力:枚举 f(k),矩阵验证。

设 f(k)=x,可以统计出 f(n) 中乘 x 的次数。

设 f(n)=x^a=m,是否可以找到最小的 x?

看题解了……

*/
posted @ 2020-11-11 19:47  George1123  阅读(23)  评论(0)    收藏  举报