• HDU 6395 Sequence 【矩阵快速幂 && 暴力】


    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=6395

    Sequence

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
    Total Submission(s): 2564    Accepted Submission(s): 999


    Problem Description
    Let us define a sequence as below

    ⎧⎩⎨⎪⎪⎪⎪⎪⎪F1F2Fn===ABCFn2+DFn1+Pn


      Your job is simple, for each task, you should output Fn module 109+7.
     
    Input
    The first line has only one integer T, indicates the number of tasks.

    Then, for the next T lines, each line consists of 6 integers, A , BCDPn.

    1T200A,B,C,D1091P,n109
     
    Sample Input
    2
    3 3 2 1 3 5
    3 2 2 2 1 4
     
    Sample Output
    36
    24
     
    Source
     

    题意概括:

    给出 A,B,C,D,P,N;

    根据函数:

    F(1)=A, F(2)=B,  F(i)=C*F(i-2)+D*F(i-1)+p/i;

    求 F( N );

    解题思路:

    一开始看错题目,以为 p/n 为 一个常数,其实题目里的 n 是变量(即题意里的 i );

    如果是常数直接构造矩阵,矩阵快速幂跑一波即可,但是这里是是变量。

    所以一开始选择了暴力 p/i ;p的范围是 1e9 果断超时。

    怎么优化呢?

    其实由于整型除法的向下取整,我们可以按 p/i 的种类分成一段一段的,这样大大缩短了暴力区间。

    AC code:

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <cmath>
     5 #define LL long long
     6 using namespace std;
     7 const int MAXN = 11;
     8 const int Mod = 1e9+7;
     9 const int NN = 3;
    10 int N, A, B, C, D, P;
    11 struct mat
    12 {
    13     LL m[MAXN][MAXN];
    14 }base, ans;
    15 
    16 mat muti(mat a, mat b)
    17 {
    18     mat res;
    19     memset(res.m, 0, sizeof(res.m));
    20     for(int i = 1; i <= NN; i++)
    21     for(int j = 1; j <= NN; j++){
    22             if(a.m[i][j]){
    23                 for(int k = 1; k <= NN; k++){
    24                     res.m[i][k] = (res.m[i][k] + a.m[i][j]*b.m[j][k])%Mod;
    25                 }
    26             }
    27         }
    28 
    29     return res;
    30 }
    31 
    32 mat qpow(mat a, int n)
    33 {
    34     mat res;
    35     memset(res.m, 0, sizeof(res.m));
    36     for(int i = 1; i <= NN; i++) res.m[i][i] = 1;
    37     while(n){
    38         if(n&1) res = muti(res, a);
    39         n>>=1;
    40         a = muti(a, a);
    41     }
    42     return res;
    43 }
    44 
    45 
    46 int main()
    47 {
    48     int K, T_case;
    49     scanf("%d", &T_case);
    50     while(T_case--){
    51         memset(base.m, 0, sizeof(base.m));
    52         memset(ans.m, 0, sizeof(ans.m));
    53         scanf("%d %d %d %d %d %d", &A, &B, &C, &D, &P, &N);
    54         if(N == 1){printf("%d
    ", A);continue;}
    55         if(N == 2){printf("%d
    ", B);continue;}
    56         else{
    57             base.m[1][2] = C;
    58             base.m[2][2] = D;
    59             base.m[2][1] = 1;
    60             base.m[3][3] = 1;
    61             base.m[3][2] = P/3;
    62             ans.m[1][1] = A;
    63             ans.m[1][2] = B;
    64             ans.m[1][3] = 1;
    65             int now = 3, x, len = 0, lst;
    66             for(;now <= N; now = lst+1){
    67                 x = P/now;
    68                 if(x != 0) lst = min(P/x, N);
    69                 else lst = N;
    70                 len = lst-now+1;
    71                 base.m[3][2] = x;
    72                 ans = muti(ans, qpow(base, len));
    73             }
    74         }
    75         printf("%lld
    ", ans.m[1][2]);
    76     }
    77 
    78     return 0;
    79 }
    View Code
  • 相关阅读:
    static关键字的定义与使用
    String类练习统计一个字符串中大小写字母及数字字符个数
    Java中String类的常用方法
    String类的特点和使用步骤
    HTB 渗透测试笔记-Lame
    消息认证-数字签名-报文鉴别-到底是什么
    docker pull 太慢了解决办法
    彻底解决Mac无线网络故障和网速慢的问题
    彻底-有效-解决-Github下载太慢的问题
    Linux中的docker报错 Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
  • 原文地址:https://www.cnblogs.com/ymzjj/p/10432689.html
Copyright © 2020-2023  润新知