首页 > 其他分享 >hdu 2604(矩阵快速幂)

hdu 2604(矩阵快速幂)

时间:2023-06-28 23:34:09浏览次数:39  
标签:2604 hdu Mat temp int res printf 矩阵 ori


题意:f和m两种字母,给出l表示有2^l个由f和m组成长度为l的字符串,如果这些字符串内包含fmf或fff子串的是一种特殊字符串,给出l问不是特殊字符串的数量是多少。
题解:先暴力把前几个l的答案跑了一下,发现有个规律f(n) = f(n - 1) + f(n - 3) + f(n - 4),试着用这个公式写了矩阵快速幂交上去过了,但后来发现这个规律是有原因的,如果以m为最后一个字符的答案有f(n - 1)个,但如果以f为结尾就不一定了,两个字符结尾会有ff,mf,然而也无法判定,所以继续三个字符结尾fff,fmf,mmf,mff,其中肯定没答案的是fff和fmf,如果以mmf为结尾解就有f(n - 3),如果以mff就无法确定,继续向前推,四个字符结尾有fmff,mmff,fmff肯定无解,那么mmff为结尾的解就有f(n - 4),自此结束,所以情况都可以判定下来,所以f(n) = f(n - 1) + f(n - 3) + f(n - 4)。构造矩阵,然后用矩阵快速幂就可以得到答案。

#include <stdio.h>
#include <string.h>
const int N = 10;
struct Mat {
    int g[N][N];
}res, ori;
int l, m;

Mat multiply(Mat x, Mat y) {
    Mat temp;
    memset(temp.g, 0, sizeof(temp.g));
    for (int i = 0; i < 4; i++)
        for (int j = 0; j < 4; j++)
            for (int k = 0; k < 4; k++)
                temp.g[i][j] = (temp.g[i][j] + x.g[i][k] * y.g[k][j]) % m;
    return temp;
}

void calc(int n) {
    while (n) {
        if (n & 1)
            ori = multiply(ori, res);
        n >>= 1;
        res = multiply(res, res);
    }
}

int main() {
    while (scanf("%d%d", &l, &m) == 2) {
        if (l == 1)
            printf("%d\n", 2 % m);
        else if (l == 2)
            printf("%d\n", 4 % m);
        else if (l == 3)
            printf("%d\n", 6 % m);
        else if (l == 4)
            printf("%d\n", 9 % m);
        else {
            memset(ori.g, 0, sizeof(ori.g));
            memset(res.g, 0, sizeof(res.g));
            res.g[0][0] = res.g[0][1] = res.g[2][0] = res.g[3][0] = res.g[1][2] = res.g[2][3] = 1;
            ori.g[0][0] = 9;
            ori.g[0][1] = 6;
            ori.g[0][2] = 4;
            ori.g[0][3] = 2;
            calc(l - 4);
            printf("%d\n", ori.g[0][0]);
        }
    }
    return 0;
}


标签:2604,hdu,Mat,temp,int,res,printf,矩阵,ori
From: https://blog.51cto.com/u_10729926/6577254

相关文章

  • hdu 1575(矩阵快速幂)
    题解:矩阵快速幂模板题。#include<stdio.h>#include<string.h>constintN=10;structMat{intg[N][N];}res,ori;intn,k;Matmultiply(Matx,Maty){Mattemp;memset(temp.g,0,sizeof(temp.g));for(inti=0;i<n;i++)......
  • hdu 5249(set + queue)
    题意:Input有大约100组数据。每组数据第一行有一个n(1≤n≤10000),代表服务记录数。接下来有n行,每一行有3种形式“inx”:代表重要值为x(0≤x≤109)的请求被推进管道。“out”:代表服务拉取了管道头部的请求。“query:代表我想知道当前管道内请求重要值的中间值.那就是......
  • poj 3233(矩阵快速幂)
    题意:给出一个矩阵A和数字k,要求出矩阵S=A+A^2+A^3+…+A^k。题解:首先A^x可以计算,然后需要折半计算,比如s(k)=(1+A^(k/2))*s(k/2),但k的奇偶不同需要分情况。#include<stdio.h>#include<string.h>constintN=35;structMat{intg[N][N];};intn,k,m......
  • hdu 5256(最长上升子序列)
    题意:我们有一个数列A1,A2…An,你现在要求修改数量最少的元素,使得这个数列严格递增。其中无论是修改前还是修改后,每个元素都必须是整数。请输出最少需要修改多少个元素。题解:这是一个很机智的想法,每个数字和它的对应位置的差值存到数组s中,n-s序列的最长上升子序列就是解。#incl......
  • hdu 3117(矩阵快速幂)
    题意:求斐波那契序列的第n个数。如果超过8位,只输出前4位和后4位。题解:后4位比较好办,直接mod10000就可以了,前4位不知道怎么求,网上看到一个人写的很详细易懂,需要用到斐波那契通项公式,详细见→传送门#include<stdio.h>#include<math.h>#include<string.h>structMat{long......
  • uva 12470(矩阵快速幂)
    题意:公式f(n)=f(n-1)+f(n-2)+f(n-3),给出n,f(1)=0,f(2)=1,f(3)=2,要求得出f(n)。题解:普通的矩阵快速幂模板题。#include<stdio.h>#include<string.h>constintMOD=1000000009;structMat{longlongg[3][3];}ori,res;longlongn;Matmultiply(......
  • hdu 5254(暴力)
    题解:暴力所有点,直到不存在可以0变1的点。#include<stdio.h>#include<string.h>constintN=505;intn,m,k,g[N][N],temp[N][N],vis[N][N];booljudge(intx,inty){if(x-1>=0&&y-1>=0){if(temp[x-1][y]&&te......
  • hdu 2855(矩阵快速幂)
    题意:计算公式题解:想推出矩阵相乘的形式,想了很久也想不出,然后看别人的题解有一个高中就学过的式子:(1+x)^n=Cn0x^n+Cn1x^(n-1)+Cn2x^(n-2)+Cn3x^(n-3)+····+Cnn然后想到斐波那契矩阵是{1,1,1,0},1看做一个单位阵{1,0,1,0},就会做了。。。#include<stdio.h>#include......
  • hdu 1241(dfs)
    ProblemDescriptionTheGeoSurvCompgeologicsurveycompanyisresponsiblefordetectingundergroundoildeposits.GeoSurvCompworkswithonelargerectangularregionoflandatatime,andcreatesagridthatdividesthelandintonumeroussquareplots.......
  • 2023-06-28《计算方法》- 陈丽娟 - 向量和矩阵基础.md
    2023-06-28《计算方法》-陈丽娟-向量和矩阵基础Matlab计算方法矩阵范数导数条件数本问补充向量和矩阵范数的相关知识,为下一章节的线性方程组的迭代法以及误差分析做准备。除了参考《计算方法》一书,还参考了华东师范大学数学学院的课程材料《迭代方法与预处理》以及陈新宇、伍......