CF1106F Lunar New Year and a Recursive Sequence——矩阵快速幂&&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$ 可以表示成 ${f_k}^x$ 的形式,也就是指数的线性递推式,用矩阵快速幂求出最终 $f_n$ 中的次数就行了。

$$\begin{bmatrix} f_k\\  f_{k-1}\\   \vdots \\  f_1 \end{bmatrix} =
\begin{bmatrix} b_1 & b_2 & \cdots  & b_k\\  1 & 0 & 0 & 0\\  \vdots  & \ddots & \vdots  & \vdots \\  0 & 0 & 1 & 0 \end{bmatrix} \cdot
\begin{bmatrix} f_{k-1}\\  f_{k-2}\\   \vdots \\  f_0 \end{bmatrix}$$

即 $F_n = B\cdot F_{n-1} = B^{n-k}F_k$

那么就是 ${f_k}^x \equiv f_n \ (mod p) $ 形式了,其中 $x$ 是已经用矩阵快速幂算出来的。

于是就是关于形如 $x^a\equiv b\pmod{p}$ 方程的求解,直接用模板。

其中998244353的原根为3,算常识了吧。

注意算矩阵快速幂时,模并不是 $p$,由欧拉定理,模是 $p-1$.

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
struct matrix
{
    int r, c;
    ll mat[101][101];
    matrix(){
        memset(mat, 0, sizeof(mat));
    }
};
const ll p = 998244353;
int k, b[110], n, m;

matrix mul(matrix A, matrix B, ll p)   //矩阵相乘
{
    matrix ret;
    ret.r = A.r; ret.c = B.c;
    for(int i = 0;i < A.r;i++)
        for(int k = 0;k < A.c;k++)
            for(int j = 0;j < B.c;j++)
            {
                ret.mat[i][j] = (ret.mat[i][j] + A.mat[i][k] * B.mat[k][j]) % p;
            }
    return ret;
}

matrix mpow(matrix A, int n, int p)
{
    matrix ret;
    ret.r = A.r; ret.c = A.c;
    for(int i = 0;i < ret.r;i++)  ret.mat[i][i] = 1;
    while(n)
    {
        if(n & 1)  ret = mul(ret, A, p);
        A = mul(A, A, p);
        n >>= 1;
    }
    return ret;
}

ll gcd(ll a, ll b)
{
    return b ? gcd(b, a%b) : a;
}

ll qpow(ll a, ll b, ll p)
{
    a = a % p;
    ll ret = 1;
    while(b)
    {
        if(b&1)  ret = ret * a % p;
        a = a * a %p;
        b >>= 1;
    }
    return ret % p;
}

map<int,int>mp;
int bsgs(int a, int b, int p){    //a^x = b (mod P),(a,p)=1,返回x,x>=1
    int m=sqrt(p)+1;mp.clear();
    for(register int i=0,res=b;i<m;++i,res=1ll*res*a%p)mp[res]=i;
    for(register int i=1,tmp=qpow(a,m,p),res=tmp;i<=m+1;++i,res=1ll*res*tmp%p)
        if(mp.count(res))return i*m-mp[res];
    return -1;
}

int  main()
{
    scanf("%d", &k);
    for(int i = 1;i <= k;i++)  scanf("%d", &b[i]);
    scanf("%d%d", &n, &m);
    matrix B;
    B.r = B.c = k;
    for(int i = 0;i < k;i++)  B.mat[0][i] = b[i+1];
    for(int i = 1;i < k;i++)  B.mat[i][i-1] = 1;

    B = mpow(B, n-k, p-1);
    int a = B.mat[0][0] % (p-1);    //注意,是模p-1 而非p

    int c = bsgs(qpow(3, a, p), m, p);
    if(c == -1)  printf("-1\n");
    else
    {
        int fk = qpow(3, c, p);
        printf("%d\n", fk);
    }
}

参考链接:https://www.cnblogs.com/bztMinamoto/p/10348641.html

原文地址:https://www.cnblogs.com/lfri/p/11511210.html

时间: 2024-10-03 15:56:45

CF1106F Lunar New Year and a Recursive Sequence——矩阵快速幂&&bsgs的相关文章

HDU 5950 - Recursive sequence - [矩阵快速幂加速递推][2016ACM/ICPC亚洲区沈阳站 Problem C]

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5950 Farmer John likes to play mathematics games with his N cows. Recently, they are attracted by recursive sequences. In each turn, the cows would stand in a line, while John writes two positive numbers

HDU 5950 Recursive sequence 矩阵快速幂

http://acm.hdu.edu.cn/showproblem.php?pid=5950 一开始以为i^4不能矩阵快速幂,但是结论是可以得,那么要怎么递推呢? 矩阵快速幂的思路都是一样的,matrix_a * matrix_b ^ n 其中,想要维护什么,就在matrix_a写,比如现在是F[n - 1], F[n - 2],我想要递推到下一项,那么就 会变成F[n], F[n - 1],这个时候,你就要寻找一下F[n]和F[n - 1]有什么关系. i^4也一样,想要从i^4 递推到 (i

5950 Recursive sequence (矩阵快速幂)

题意:递推公式 Fn = Fn-1 + 2 * Fn-2 + n*n,让求 Fn; 析:很明显的矩阵快速幂,因为这个很像Fibonacci数列,所以我们考虑是矩阵,然后我们进行推公式,因为这样我们是无法进行运算的.好像有的思路,最后也没想出来,还是参考的大牛的博客 http://blog.csdn.net/spring371327/article/details/52973534 那是讲的很详细了,就不多说了,注意这个取模不是1e9+7,一开始忘了.. 代码如下: #pragma comment

Uva10689 Yet another Number Sequence ( 矩阵快速幂 )

Uva 10689Yet another Number Sequence(  矩阵快速幂  ) 题意: 就是矩阵快速幂,没什么好说的. 分析: 其实还是斐波那契数列.只是最后对应的矩阵不是(1,1)是(a,b)了 MOD = 1; for( int i = 0; i < m; ++i ) MOD *= 10; 代码 #include <cstdio> #include <cstring> #include <algorithm> using namespace s

HDU5950-Recursive sequence(矩阵快速幂)

题目链接:Recursive sequence 题意:给出n头母牛,第一头报a,第二头报b,第i头报f[i-2]*2+f[i-1]+i^4,问第n头母牛报数多少 分析:N,a,b<2^31,果断矩阵快速幂,关键是要推出公式,公式如下,仅作参考 1 0 0 0 0 0 0        1               1 1 1 0 0 0 0 0        i                i+1 1 2 1 0 0 0 0       i2              (i+1)2 1 3

UVA - 10689 Yet another Number Sequence 矩阵快速幂

                  Yet another Number Sequence Let’s de?ne another number sequence, given by the following function:f(0) = af(1) = bf(n) = f(n − 1) + f(n − 2), n > 1When a = 0 and b = 1, this sequence gives the Fibonacci Sequence. Changing the values

hdu-5667 Sequence(矩阵快速幂+费马小定理+快速幂)

题目链接: Sequence Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Others) Problem Description Holion August will eat every thing he has found. Now there are many foods,but he does not want to eat all of them at once,so he fi

HDU 1005 Number Sequence 矩阵快速幂

Number Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 236241    Accepted Submission(s): 60070 Problem Description A number sequence is defined as follows: f(1) = 1, f(2) = 1, f(n) = (A

hdu 5667 Sequence 矩阵快速幂

题目链接:hdu 5667 Sequence 思路:因为fn均为a的幂,所以: 这样我们就可以利用快速幂来计算了 注意: 矩阵要定义为long long,不仅仅因为会爆,还会无限超时 要对a%p==0特判,以为可能出现指数%(p-1)==0的情况,那么在快速幂的时候返回的结果就是1而不是0了 /************************************************************** Problem:hdu 5667 User: youmi Language: