zoukankan      html  css  js  c++  java
  • hdu 6395Sequence【矩阵快速幂】【分块】

    Sequence

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


     

    Problem Description

    Let us define a sequence as below

    ⎧⎩⎨⎪⎪⎪⎪⎪⎪F1F2Fn===ABC⋅Fn−2+D⋅Fn−1+⌊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 , B, C, D, P, n.

    1≤T≤200≤A,B,C,D≤1091≤P,n≤109

     

    Sample Input

    
     

    2 3 3 2 1 3 5 3 2 2 2 1 4

     

    Sample Output

    
     

    36 24

     

    Source

    2018 Multi-University Training Contest 7

     

    Recommend

    chendu   |   We have carefully selected several similar problems for you:  6408 6407 6406 6405 6404 

    学习了一个新的递推求数的方法

    通过构造矩阵 用矩阵递推 用矩阵快速幂优化 可以用来求一个随机的很大的数的值

    矩阵快速幂的写法 O(logn)

    这道题还有一点特别的是 后面的常数项是会变化的 但是他是分段的

    所以就分块的来求 因为要知道乘的次数所以每次要求一下这个区间有多少个数

    c++TLE g++AC

    
    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<stack>
    #define inf 1e18
    using namespace std;
    
    long long t, a, b, c, d, p, n;
    const int mod = 1e9 + 7;
    struct mat{
        long long m[3][3];
        mat(){
            memset(m, 0, sizeof(m));
        }
        void init()
        {
            memset(m, 0, sizeof(m));
            for(int i = 0; i < 3; i++){
                m[i][i] = 1;
            }
        }
        friend mat operator * (mat a, mat b)
        {
            mat c;
            for(int i = 0; i < 3; i++){
                for(int j = 0; j < 3; j++){
                    for(int k = 0; k < 3; k++){
                        c.m[i][j] += a.m[i][k] * b.m[k][j];
                        c.m[i][j] %= mod;
                    }
                }
            }
            return c;
        }
    };
    
    mat pow_mat(mat a, int b)
    {
        mat c;
        c.init();
        while(b){
            if(b & 1){
                c = c * a;
            }
            a = a * a;
            b >>= 1;
        }
        return c;
    }
    
    int main()
    {
        scanf("%lld", &t);
        while(t--){
            scanf("%lld%lld%lld%lld%lld%lld", &a, &b, &c, &d, &p, &n);
            if(n == 1){
                printf("%lld
    ", a);
                continue;
            }
            mat f;
            f.m[0][0] = d;
            f.m[1][0] = c;
            f.m[2][0] = f.m[0][1] = f.m[2][2] = 1;
            mat g;
            g.m[0][0] = b;
            g.m[0][1] = a;
    
            if(p >= n){
                for(long long i = 3, j; i <= n; i = j + 1){
                    j = p / (p / i);//个数
                    g.m[0][2] = p / i;
                    mat po = pow_mat(f, min(j - i + 1, n - i + 1));
                    g = g * po;
                }
            }
            else{
                for(long long i = 3, j; i <= p; i = j + 1){
                    j = p / (p / i);
                    g.m[0][2] = p / i;
                    mat po = pow_mat(f, j - i + 1);
                    g = g * po;
                }
                mat po;
                g.m[0][2] = 0;
                if(p < 3){
                    po = pow_mat(f, n - 2);
                }
                else{
                    po = pow_mat(f, n - p);
                }
                g = g * po;
            }
            printf("%lld
    ", g.m[0][0]);
        }
        return 0;
    }
    
  • 相关阅读:
    iOS多线程之NSThread详解
    iOS中NSScanner 的用法
    自己的第一篇博客
    useradd与adduser的区别
    drop、truncate和delete的区别
    开启ipv6支持
    linux主机hang住echo 0 > /proc/sys/kernel/hung_task_timeout_secs disables this message
    xfs文件系统修复方法https://blog.csdn.net/yuanfang_way/article/details/78700089
    mysql表死锁查询
    系统丢包net.netfilter.nf_conntrack_max 超限查看
  • 原文地址:https://www.cnblogs.com/wyboooo/p/9643388.html
Copyright © 2011-2022 走看看