zoukankan      html  css  js  c++  java
  • HDU Queuing (递推+矩阵快速幂)

    题面

    Problem Description
    Queues and Priority Queues are data structures which are known to most computer scientists. The Queue occurs often in our daily life. There are many people lined up at the lunch time.

    Now we define that ‘f’ is short for female and ‘m’ is short for male. If the queue’s length is L, then there are 2L numbers of queues. For example, if L = 2, then they are ff, mm, fm, mf . If there exists a subqueue as fmf or fff, we call it O-queue else it is a E-queue.
    Your task is to calculate the number of E-queues mod M with length L by writing a program.

    Input
    Input a length L (0 <= L <= 10 [sup]6[/sup]) and M.

    Output
    Output K mod M(1 <= M <= 30) where K is the number of E-queues with length L.

    思路

    其实刚看到这个题目,我是想推组合数学来着的,后面wa掉了,这个想法猝死。看了题解,是这样的,这个题目是可以递推的,我们考虑末尾的一个字母和前一项的关系,层层递推可以得到通项是L=(L-1)+(L-3)+(L-4)。但我并不知道为什么会要矩阵快速幂,这个题的数据量按道理来说不大,据说是被卡空间了?网上好像也有开char数组来递推过题的。我们还是讲一下快速幂做法,我们构造一个辅助矩阵,然后做n-4次的快速幂运算,最后和f1-f4去相乘得出我们要的ans。构造辅助矩阵的方法,因为往往他自身要去做一个快速幂,所以这个矩阵必须是一个n乘n阶的一个矩阵,其次我们每次要把每一项都向前推一项,所以除了题目推出的第一列的递推式,其余都要构造一个往前推的式子。

    代码实现

    #include<cstring>
    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int inf =0x3f3f3f3f;
    const int maxn=5;
    struct Matrix {
        int maze[maxn][maxn];
        Matrix () {
            memset (maze,0,sizeof (maze));
        }
    };
    int f[10];
    int n,mod;
    Matrix mul (Matrix a,Matrix b) {
        Matrix ans;
        for (int i=1;i<=4;i++)
         for (int j=1;j<=4;j++) {
             for (int k=1;k<=4;k++) {
                 ans.maze[i][j]=(ans.maze[i][j]+a.maze[i][k]*b.maze[k][j])%mod;
             }
         }
         return ans;
    }
    Matrix fast_pow (Matrix a,int x) {
       Matrix ans;
       for (int i=1;i<=4;i++) ans.maze[i][i]=1;
       while (x) {
           if (x&1) ans=mul (ans,a);
           a=mul (a,a);
           x>>=1;
       }
       return ans;
    }
    int main () { 
        while (cin>>n>>mod) {
           memset (f,0,sizeof (f));
           f[1]=2; f[2]=4; f[3]=6; f[4]=9;
           Matrix t;
           t.maze[1][1]=t.maze[3][1]=t.maze[4][1]=1;
           t.maze[1][2]=t.maze[2][3]=t.maze[3][4]=1;
           if (n==1) {
               cout<<2%mod<<endl;
               continue;
           }
           else if (n==2) {
              cout<<4%mod<<endl;
              continue;
           }
           else if (n==3) {
               cout<<6%mod<<endl;
               continue;
           }
           else if (n==4) {
               cout<<9%mod<<endl;
           }
           else {
               Matrix fin=fast_pow (t,n-4);
               int ans=0;
               for (int i=1;i<=4;i++) {
                   ans=(ans+fin.maze[i][1]*f[5-i])%mod;
               }
               cout<<ans<<endl;
           }
           
        }   
        return 0;
    }
    
  • 相关阅读:
    【Luogu P5515】[MtOI2019]灵梦的计算器
    简易的命令行入门教程
    8个接私活的网站,只要你有码,那“我”就有钱
    单表查询必会13条
    「Django」rest_framework学习系列-路由
    Linux下将时间修改为当地时间(通过ntpdate服务)
    iptables拒绝发起大量请求(针对单IP地址)
    .webp格式win7无法显示缩略图
    永久修改/etc/proc下的项的配置文件
    通过vsftpd实现虚拟用户登录,不同的用户登录不同的目录,使用不同的权限
  • 原文地址:https://www.cnblogs.com/hhlya/p/13288613.html
Copyright © 2011-2022 走看看