CF1106F Lunar New Year and a Recursive Sequence

又傻掉了呢

看到连乘显然直接转原根变成线性齐次递推式。

矩阵乘法求一发。

然后分析一下发现是个x^k=m的形式。

按照套路解一下高次方程就好了。

需要用到exgcd和bsgs。

#include<iostream>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<ctime>
#include<map>
#include<cstdlib>
#include<algorithm>
#define N 120
#define L 110
#define eps 1e-7
#define inf 1e9+7
#define db double
#define ll long long
#define ldb long double
using namespace std;
inline ll read()
{
    char ch=0;
    ll x=0,flag=1;
    while(!isdigit(ch)){ch=getchar();if(ch==‘-‘)flag=-1;}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-‘0‘;ch=getchar();}
    return x*flag;
}
const ll g=3;
const ll p=998244352;
const ll mo=998244353;
struct matrix
{
    ll s[N][N];
    void clear(){memset(s,0,sizeof(s));}
};
matrix operator*(matrix a,matrix b)
{
    matrix ans;
    ans.clear();
    for(ll i=0;i<=L;i++)
      for(ll j=0;j<=L;j++)
        for(ll k=0;k<=L;k++)
        ans.s[i][j]=(ans.s[i][j]+(a.s[i][k]*b.s[k][j]%p))%p;
    return ans;
}
matrix ksm(matrix x,ll k)
{
    matrix ans;
    ans.clear();
    for(ll i=0;i<=L;i++)ans.s[i][i]=1;
    while(k)
    {
        if(k&1)ans=ans*x;
        k>>=1;
        x=x*x;
    }
    return ans;
}
matrix f;
ll qpow(ll x,ll k)
{
    ll ans=1;
    while(k)
    {
        if(k&1)ans=ans*x%mo;
        k>>=1;
        x=x*x%mo;
    }
    return ans;
}
ll X,Y;
ll exgcd(ll a,ll b)
{
    if(!b){X=1,Y=0;return a;}
    ll d=exgcd(b,a%b);
    ll t=X;X=Y,Y=t-(a/b)*Y;
    return d;
}
map<ll,ll>S;
map<ll,ll>::iterator it;
ll bsgs(ll a,ll n)
{
    S.clear();
    ll x=1,k=1,len=sqrt(mo);
    for(ll i=0;i<len;i++,x=(x*a)%mo)
    if(S.find(x)==S.end())S.insert(pair<ll,ll>{x,i});
    for(ll i=0;i<mo;i+=len,k=(k*x)%mo)
    {
        exgcd(k,mo),X=((X%mo+mo)%mo*n)%mo;
        it=S.find(X);
        if(it!=S.end())return i+(it->second);
    }
    return 0;
}
int main()
{
    ll k=read();
    f.clear();
    for(ll i=1;i<k;i++)f.s[i+1][i]=1;
    for(ll i=1;i<=k;i++)f.s[k-i+1][k]=read();
    ll n=read(),m=read();
    f=ksm(f,n-k);f.s[k][k]=(f.s[k][k]%p+p)%p;
    ll o=bsgs(g,m),d=exgcd(f.s[k][k],p);
    if(o%d==0)
    {
        X=X%p*(o/d)%p;
        printf("%lld",qpow(g,(X%p+p)%p));
    }
    else printf("-1");
    return 0;
}

原文地址:https://www.cnblogs.com/Creed-qwq/p/10349300.html

时间: 2024-11-06 09:25:42

CF1106F Lunar New Year and a Recursive Sequence的相关文章

CF1106F Lunar New Year and a Recursive Sequence(矩阵快速幂+bsgs+exgcd)

题面 传送门 前置芝士 \(BSGS\) 什么?你不会\(BSGS\)?百度啊 原根 对于素数\(p\)和自然数\(a\),如果满足\(a^x\equiv 1\pmod{p}\)的最小的\(x\)为\(p-1\),那么\(a\)就是\(p\)的一个原根 离散对数 对于素数\(p\),以及\(p\)的一个原根\(g\),定义\(y\)为\(x\)的离散对数,当且仅当\(g^y\equiv x\pmod{p}\),记\(y\)为\(ind_g x\).不难发现原数和离散对数可以一一对应.也不难发现离

CF1106F Lunar New Year and a Recursive Sequence——矩阵快速幂&amp;&amp;bsgs

题意 设 $$f_i = \left\{\begin{matrix}1 , \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \  i < k\\ \prod_{j=1}^k f_{i-j}^{b_j} \ mod \ p, \ \ \ \ \ i > k\end{matrix}\right.$$ 求 $f_k$($1 \leq f_k < p$),使得 $f_m = n$.($1 \leq k\leq 100$) 分析 $f_n$ 可以表示

Codeforces 536F Lunar New Year and a Recursive Sequence | BSGS/exgcd/矩阵乘法

我诈尸啦! 高三退役选手好不容易抛弃天利和金考卷打场CF,结果打得和shi一样--还因为queue太长而unrated了!一个学期不敲代码实在是忘干净了-- 没分该没分,考题还是要订正的 =v= 欢迎阅读本题解! P.S. 这几个算法我是一个也想不起来了 TAT 题目链接 Codeforces 536F Lunar New Year and a Recursive Sequence 新年和递推数列 题意描述 某数列\(\{f_i\}\)递推公式:\[f_i = (\prod_{j=1}^kf_{

Codeforces 1106F Lunar New Year and a Recursive Sequence (数学、线性代数、线性递推、数论、BSGS、扩展欧几里得算法)

哎呀大水题..我写了一个多小时..好没救啊.. 数论板子X合一? 注意: 本文中变量名称区分大小写. 题意: 给一个\(n\)阶递推序列\(f_k=\prod^{n}_{i=1} f_{k-i}b_i\mod P\)其中\(P=998244353\), 输入\(b_1,b_2,...,b_n\)以及已知\(f_1,f_2,...,f_{n-1}=1\), 再给定一个数\(m\)和第\(m\)项的值\(f_m\), 求出一个合法的\(f_n\)值使得按照这个值递推出来的序列满足第\(m\)项的值为

HDu 5950 Recursive sequence(矩阵快速幂)

Recursive sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1323    Accepted Submission(s): 589 Problem Description Farmer John likes to play mathematics games with his N cows. Recently,

HDU 5950 Recursive sequence 【递推+矩阵快速幂】 (2016ACM/ICPC亚洲区沈阳站)

Recursive sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 249    Accepted Submission(s): 140 Problem Description Farmer John likes to play mathematics games with his N cows. Recently, t

Recursive sequence HDU - 5950

Recursive sequence HDU - 5950 题意:求 f(n) = f(n?1)+2*f(n?2)+n4,其中 f(1)=a,f(2)=b 利用矩阵加速~ 比较坑的是mod=2147493647....不是2147483647,用int WA了多次=_=|| 1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 const ll mod=2147493647; 5 const int

HDU 4914 Linear recursive sequence(矩阵乘法递推的优化)

题解见X姐的论文 矩阵乘法递推的优化,只是mark一下.. HDU 4914 Linear recursive sequence(矩阵乘法递推的优化)

hdu 5950 Recursive sequence

Recursive sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 5120    Accepted Submission(s): 2197 Problem Description Farmer John likes to play mathematics games with his N cows. Recently,