Reading comprehension HDU - 4990 (矩阵快速幂 or 快速幂+等比数列)

for(i=1;i<=n;i++)
{
      if(i&1)ans=(ans*2+1)%m;
      else ans=ans*2%m;
} 

给定n,m。让你用O(log(n))以下时间算出ans。

打表,推出 ans[i] = 2^(i-1) + f[i-2]

故 i奇数:ans[i] = 2^(i-1) + 2^(i-3) ... + 1;

  i偶数:ans[i] = 2^(i-1) + 2^(i-3) ... + 2;

故可以用等比数列求和公式。

公式涉及除法。我也没弄懂为啥不能用逆元,貌似说是啥逆元可能不存在。

所以a/b % m == a%(b*m) / b 直接搞了。

#include <cstdio>
#include<iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include<vector>
typedef long long LL;

LL quick_pow(LL a, LL b, LL m)
{
    LL ans = 1, base = a % m;
    while(b)
    {
        if (b & 1) ans = (ans * base) % m;
        base = (base * base) % m;
        b >>= 1;
    }
    return ans;
}

int main()
{
    LL n, m;

    while(~scanf("%lld%lld", &n, &m))
    {
        LL a1 = (n % 2) ? 1 : 2;
        LL sum = a1 * (quick_pow(4, (n+1)/2, 3*m) - 1);
        LL ans = (sum % (3 * m)) / 3;
        printf("%lld\n", ans);
    }
}

第一次学矩阵快速幂,再贴个矩阵快速幂的板子。

f[n] = f[n-1] + 2 * f[n-2] + 1,故可以构造矩阵

f[n-2] f[n-1] 1        0 2 0             f[n-1]   f[n]  1
0      0      0        1 1 0       =      0       0     0
0      0      0        0 1 1              0       0     0

模板来源:https://blog.csdn.net/u012860063/article/details/39123605

#include <cstdio>
#include<iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include<vector>
typedef long long LL;

struct Matrix
{
    LL m[5][5];
} I, A, B, T;

LL a,b,n, mod;
int ssize = 3;

Matrix Mul(Matrix a,Matrix b)
{
    int i,j,k;
    Matrix c;
    for (i = 1; i <= ssize; i++)
        for(j = 1; j <= ssize; j++)
        {
            c.m[i][j]=0;
            for(k = 1; k <= ssize; k++)
            {
                c.m[i][j]+=(a.m[i][k]*b.m[k][j]);
                c.m[i][j]%=mod;
            }
        }

    return c;
}

Matrix quickpagow(int n)
{
    Matrix m = A, b = I;
    while(n)
    {
        if(n & 1) b = Mul(b, m);
        n >>= 1;
        m = Mul(m, m);
    }
    return b;
}

int main()
{
    while(~scanf("%lld%lld",&n, &mod))
    {
        memset(I.m,0,sizeof(I.m));
        memset(A.m,0,sizeof(A.m));
        memset(B.m,0,sizeof(B.m));

        for(int i = 1; i <= ssize; i++) I.m[i][i] = 1;
        //I是单位矩阵

        B.m[1][1] = 1, B.m[1][2] = 2, B.m[1][3] = 1;
        A.m[1][2] = 2;
        A.m[2][1] = A.m[2][2] = A.m[3][2] = A.m[3][3] = 1;

        if(n == 1) printf("%lld\n",1 % mod);
        else if(n == 2) printf("%lld\n",2 % mod);
        else
        {
            T = quickpagow(n-2);
            T = Mul(B, T);
            printf("%lld\n",T.m[1][2] % mod);
        }
    }
}

原文地址:https://www.cnblogs.com/ruthank/p/10575637.html

时间: 2024-10-10 15:04:50

Reading comprehension HDU - 4990 (矩阵快速幂 or 快速幂+等比数列)的相关文章

Reading comprehension HDU - 4990

Read the program below carefully then answer the question. #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include<iostream> #include <cstring> #include <cmath> #include <algorithm> #inclu

HDU 4990 Reading comprehension (找规律+矩阵快速幂)

题目链接:HDU 4990 Reading comprehension 题目给的一个程序其实就是一个公式:当N=1时 f[n]=1,当n>1时,n为奇数f[n]=2*f[n-1]+1,n为偶数f[n]=2*f[n-1]. 先不取模,计算前十个找规律.得到一个递推公式:f[n]=2*f[n-2]+f[n-1]+1 然后快速幂解决之. 给出一个神奇的网站(找数列通项):http://oeis.org/ AC代码: #include<stdio.h> #include<string.h&

hdu-4990 Reading comprehension(快速幂+乘法逆元)

题目链接: Reading comprehension Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 32768/32768 K (Java/Others) Problem Description Read the program below carefully then answer the question.#pragma comment(linker, "/STACK:1024000000,1024000000"

HDU 3306 Another kind of Fibonacci(快速幂矩阵)

题目链接 构造矩阵 看的题解,剩下的就是模板了,好久没写过了,注意取余. #include <cstring> #include <cstdio> #include <string> #include <iostream> #include <algorithm> #include <vector> #include <queue> using namespace std; #define MOD 10007 #defin

HDU 4965 矩阵快速幂

顺手写了下矩阵类模板 利用到矩阵乘法的交换律 (A*B)^n == A * (B*A)^n-1 *B #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <vector> #include <utility> #include <stack> #includ

hdu 4965 矩阵快速幂 矩阵相乘性质

Fast Matrix Calculation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 170    Accepted Submission(s): 99 Problem Description One day, Alice and Bob felt bored again, Bob knows Alice is a gir

hdu 4549 M斐波那契数列(矩阵快速幂,快速幂降幂)

http://acm.hdu.edu.cn/showproblem.php?pid=4549 f[0] = a^1*b^0%p,f[1] = a^0*b^1%p,f[2] = a^1*b^1%p.....f[n] = a^fib[n-1] * b^fib[n-2]%p. 这里p是质数,且a,p互素,那么我们求a^b%p,当b很大时要对b降幂. 因为a,p互素,那么由费马小定理知a^(p-1)%p = 1.令b = k*(p-1) + b',a^b%p = a^(k*(p-1)+b')%p = a

快速乘、快速幂(矩阵快速幂)

当mod一个大数p的时候,还有进行乘法的时候可能会爆long long的时候,就用快速乘或者快速幂. 参考:http://www.cnblogs.com/whywhy/p/5066730.html 先上模板: 快速乘: ll multi(ll a,ll b,ll m) { ll ans=0; while(b) { if(b&1) (ans+=a) %= m; (a=a*2) %= m; b/=2; } return ans; } 快速幂: ll pow_mod(ll a,ll b,ll m) {

hdu 4291 矩阵幂 循环节

http://acm.hdu.edu.cn/showproblem.php?pid=4291 凡是取模的都有循环节-----常数有,矩阵也有,而且矩阵的更神奇: g(g(g(n))) mod 109 + 7  最外层MOD=1e9+7  可以算出g(g(n))的循环节222222224,进而算出g(n)的循环节183120LL,然后由内而外计算即可 注释掉的是求循环节的代码 //#pragma comment(linker, "/STACK:102400000,102400000")