开始了他的高速功率矩阵

通常用于加速复发。

简单地。为fib有列。f0 = 1。f1 = 1,fn = fn-1 + fn-2(n >= 2)。

则对于fn有:

一般的。对于fn = A1*f(n-1) + A2*f(n-2)  + .... +A(n-1)*f1,有:

又由于矩阵乘法满足结合律,所以能够用高速幂来求A^n,从而达到递推的效果。

顺便即一个小技巧:

以POJ 3233为例

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <cmath>
#include <stack>
#include <map>

#pragma comment(linker, "/STACK:1024000000");
#define EPS (1e-8)
#define LL long long
#define ULL unsigned long long
#define _LL __int64
#define INF 0x3f3f3f3f

using namespace std;

int Mod;

const int MAXN = 61;

struct Mat
{
    LL mat[MAXN][MAXN];
    int r,c;

    void Init(int val,int R,int C)
    {
        r = R,c = C;
        for(int i = 1;i <= r; ++i)
            for(int j = 1;j <= c; ++j)
                if(i != j)
                    mat[i][j] = 0;
                else
                    mat[i][j] = val;
    }
};

Mat MatrixMult(Mat a,Mat b)
{
    Mat p;
    p.Init(0,a.r,b.c);

    for(int i = 1;i <= a.r; ++i)
    {
        for(int j = 1;j <= b.c; ++j)
        {
            for(int k = 1;k <= b.r; ++k)
            {
                p.mat[i][j] += a.mat[i][k]*b.mat[k][j];
                p.mat[i][j] %= Mod;
            }
        }
    }

    return p;
}

Mat QuickMult(_LL k,Mat coe)
{
    Mat p;

    p.Init(1,coe.r,coe.c);

    while(k >= 1)
    {
        if(k&1)
            p = MatrixMult(p,coe);
        coe = MatrixMult(coe,coe);
        k >>= 1;
    }

    return p;
}

int main()
{
    _LL n,k,m;

    int i,j;

    Mat A,B;

    scanf("%lld %lld %lld",&n,&k,&m);

    Mod = m;

    for(i = 1;i <= n; ++i)
    {
        for(j = 1;j <= n; ++j)
            scanf("%lld",&A.mat[i][j]);
    }

    for(i = 1;i <= n; ++i)
    {
        for(j = 1;j <= n; ++j)
        {
            if(i == j)
                A.mat[i][j+n] = 1;
            else
                A.mat[i][j+n] = 0;
        }
    }

    for(i = 1;i <= n; ++i)
    {
        for(j = 1;j <= n; ++j)
        {
            A.mat[i+n][j] = 0;
        }
    }

    for(i = 1;i <= n; ++i)
    {
        for(j = 1;j <= n; ++j)
        {
            if(i == j)
                A.mat[i+n][j+n] = 1;
            else
                A.mat[i+n][j+n] = 0;
        }
    }

    A.r = 2*n,A.c = 2*n;

    A = QuickMult(k+1,A);

    for(i = 1;i <= n; ++i)
    {
        if(A.mat[i][i+n])
            A.mat[i][i+n]--;
        else
            A.mat[i][i+n] = m-1;
    }

    for(i = 1;i <= n; ++i)
    {
        for(j = 1;j <= n; ++j)
        {
            printf("%lld",A.mat[i][j+n]);
            if(j == n)
                printf("\n");
            else
                printf(" ");
        }
    }

    return 0;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

时间: 2024-10-10 10:14:17

开始了他的高速功率矩阵的相关文章

poj3744高速功率矩阵+可能性DP

Scout YYF I Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4410   Accepted: 1151 Description YYF is a couragous scout. Now he is on a dangerous mission which is to penetrate into the enemy's base. After overcoming a series difficulties,

HDU 2842 Chinese Rings(矩阵高速功率+递归)

职务地址:HDU 2842 这个游戏是一个九连环的游戏. 如果当前要卸下前n个环.由于要满足前n-2个都卸下,所以要先把前n-2个卸下.须要f(n-2)次.然后把第n个卸下须要1次,然后这时候要卸下第n-1个.然后此时前n-2个都已经被卸下了.这时候把前n-2个都卸下与都装上所需的次数是一样的.由于卸下与装上的规则是一样的. 所以又须要f(n-2)次.这时候前n-1个都在上面,卸下前n-1个须要f(n-1)次. 所以.总共须要2*f(n-2)+f(n-1)+1次. 然后构造例如以下矩阵. 1,2

VOJ 1067 Warcraft III 守望者的烦恼 (矩阵高速功率+dp)

主题链接 明显的 dp[n] = dp[n-k] + dp[n-k+1] + ... +dp[n-1]; 然后要用矩阵来优化后面的状态转移. 也就是矩阵 0 1 0 0    a     b 0 0 1 0 * b =  c 0 0 0 1    c     d 1 1 1 1    d    a+b+c+d 然后跑高速幂 #include <iostream> #include <cstdio> #include <algorithm> #include <cm

POJ 3070 Fibonacci(矩阵高速功率)

职务地址:POJ 3070 用这个题学会了用矩阵高速幂来高速求斐波那契数. 依据上个公式可知,第1行第2列和第2行第1列的数都是第n个斐波那契数.所以构造矩阵.求高速幂就可以. 代码例如以下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #include

NYOJ 298 相变点(矩阵高速功率)

点的变换 时间限制:2000 ms  |  内存限制:65535 KB 难度:5 描写叙述 平面上有不超过10000个点.坐标都是已知的.如今可能对全部的点做下面几种操作: 平移一定距离(M),相对X轴上下翻转(X),相对Y轴左右翻转(Y),坐标缩小或放大一定的倍数(S),全部点对坐标原点逆时针旋转一定角度(R). 操作的次数不超过1000000次,求终于全部点的坐标. 提示:假设程序中用到PI的值,能够用acos(-1.0)获得. 输入 仅仅有一组測试数据 測试数据的第一行是两个整数N,M,分

开发汉澳sinox64位,对接汉澳矩阵电脑

汉澳矩阵电脑刚刚不久前提出,即使完全设计出了汉澳矩阵电脑线路图,要在上面运行操作系统必须有矩阵操作系统.汉澳sinox64位操作系统并不是矩阵操作系统,只是更为接近. 汉澳矩阵电脑如果插有16个矩阵单元,矩阵单元上有CPU和内存,内存至少2G,16片就是32G内存,因此母版上的矩阵操作系统要寻址16个矩阵单元,就必须能寻址至少32G内存.而目前汉澳2013只是32位操作系统,只能寻址4G以内的内存.如果要访问超过4G内存需要用类似段选择子这样的硬件来辅助完成,而64位操作系统可以寻址170亿G以

DOA——MUSIC算法

[未完待续] 一.MUSIC 1. clear all; %产生三信源,角度分别为-40°.30°.45°,采用8PSK调制,滚降系数为0.5的平方根升余弦滤波 Nsym=500;%符号个数 Fsym=1;%符号速率 M=3;%一个符号对应的比特数 Fbit=M*Fsym;%比特速率 Nsour=3;%信源数 Angle=[5,15,35];%信源的来波方向 Fc=10;%载波频率 Fs=100;%抽样频率 R=0.5;%滚降因子 Del=5;%群延迟因子 % Nsamp=50;%采样点数或者快

涛哥的Python脚本工具箱之生成带Logo的二维码

近期须要在二维码上加Logo,网上没有找到好用的,于是自己用python写了一个. 须要安装qrcode,PIL库 二维码简称 QR Code(Quick Response Code),学名为高速响应矩阵码,是二维条码的一种.由日本的 Denso Wave 公司于 1994 年发明. 现随着智能手机的普及.已广泛应用于寻常生活中,比如商品信息查询.社交好友互动.网络地址訪问等等. 安装 Python 的二维码库 -- qrcode pip install qrcode 因为生成 qrcode 图

HDU 1588 Gauss Fibonacci(矩阵高速幂+二分等比序列求和)

HDU 1588 Gauss Fibonacci(矩阵高速幂+二分等比序列求和) ACM 题目地址:HDU 1588 Gauss Fibonacci 题意: g(i)=k*i+b;i为变量. 给出k,b,n,M,问( f(g(0)) + f(g(1)) + ... + f(g(n)) ) % M的值. 分析: 把斐波那契的矩阵带进去,会发现这个是个等比序列. 推倒: S(g(i)) = F(b) + F(b+k) + F(b+2k) + .... + F(b+nk) // 设 A = {1,1,