zoukankan      html  css  js  c++  java
  • HDU 6395 Sequence(分段矩阵快速幂)题解

    题意:

    已知(A,B,C,D,P,n)以及

    [left{ egin{aligned} & F_1 = A \ & F_2 = B\ & F_n = C*F_{n-2} + D*F_{n-2}+lfloor(frac{P}{n}) floor end{aligned} ight. ]

    ,求(F_n mod (1e9e+7))(n leq 1e9)

    思路:

    显然(lfloor(frac{P}{n}) floor)相同的情况是有区间的,那么直接分区间分段矩阵快速幂。

    代码:

    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<cmath>
    #include<cstdio>
    #include<string>
    #include<vector>
    #include<cstring>
    #include<sstream>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    const int maxn = 100000 + 5;
    const int INF = 0x3f3f3f3f;
    const ull seed = 131;
    const ll MOD = 1e9 + 7;
    const double eps = 1e-8;
    using namespace std;
    struct Mat{
        ll s[3][3];
        Mat(){
            memset(s, 0, sizeof(s));
        }
        void init(){
            for(int i = 0; i < 3; i++)
                s[i][i] = 1;
        }
    };
    Mat pmul(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.s[i][j] = (c.s[i][j] + a.s[i][k] * b.s[k][j]) % MOD;
                }
            }
        }
        return c;
    }
    Mat ppow(Mat a, ll b){
        Mat ret;
        ret.init();
        while(b){
            if(b & 1) ret = pmul(ret, a);
            a = pmul(a, a);
            b >>= 1;
        }
        return ret;
    }
    int main(){
        int T;
        scanf("%d", &T);
        while(T--){
            ll a, b, c, d, p, n;
            scanf("%lld%lld%lld%lld%lld%lld", &a, &b, &c, &d, &p, &n);
            Mat f, t, temp;
            t.s[0][0] = d, t.s[1][0] = c, t.s[2][0] = 1, t.s[0][1] = 1, t.s[2][2] = 1;
            f.s[0][0] = b, f.s[0][1] = a;
    
            for(int i = 3; i <= n; ){
                ll l, r, pn = p / i;
                if(pn > 0)
                    l = i, r = min(n, (p - p % pn) / pn);
                else
                    l = i, r = n;
                f.s[0][2] = pn;
                temp = ppow(t, r - l + 1);
                f = pmul(f, temp);
                i = r + 1;
            }
    
            printf("%lld
    ", f.s[0][0]);
        }
        return 0;
    }
    
    
    
    
  • 相关阅读:
    microsoft visual studio 不能逐句执行?
    【转】字符编码笔记:ASCII,Unicode和UTF-8
    【PNG格式中文详解】
    PHP 下载网络图片
    Install MongoDB on Windows (Windows下安装MongoDB)
    S2SH商用后台权限系统第二讲
    S2SH商用后台权限系统第一讲
    linux 常用命令
    简单的angular表单验证指令
    angular随笔
  • 原文地址:https://www.cnblogs.com/KirinSB/p/11417739.html
Copyright © 2011-2022 走看看