zoukankan      html  css  js  c++  java
  • bzoj4547

    矩阵乘法

    看成了合并果子。。。

    就是斐波那契数列,只是有负数的时候,先把负数变成正的,然后矩乘

    矩乘还是用单位举矩阵记录快速幂的矩阵比较保险

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N = 100010;
    const ll mod = 10000007ll;
    int n, k;
    ll ans;
    ll a[N];
    struct mat {
        ll a[4][4];
        mat() { memset(a, 0, sizeof(a)); }
        mat friend operator * (const mat &a, const mat &b) {
            mat ret;
            memset(ret.a, 0, sizeof(ret.a));
            for(int i = 0; i < 3; ++i)
                for(int j = 0; j < 3; ++j)
                    for(int k = 0; k < 3; ++k) ret.a[i][j] = (ret.a[i][j] + a.a[i][k] * b.a[k][j] % mod) % mod;
            return ret;
        }
    } A, B, tmp;
    int main()
    {
        scanf("%d%d", &n, &k);
        for(int i = 1; i <= n; ++i) scanf("%lld", &a[i]), ans = ((ans + a[i]) % mod + mod) % mod;
        sort(a + 1, a + n + 1);
        while(a[n - 1] < 0 && k) 
        {
            a[n - 1] += a[n];
            --k;
            ans = ((ans + a[n - 1]) % mod + mod) % mod;
        }   
        A.a[0][0] = 1; A.a[0][1] = 1; A.a[0][2] = 0;
        A.a[1][0] = 1; A.a[1][1] = 0; A.a[1][2] = 0;
        A.a[2][0] = 1; A.a[2][1] = 1; A.a[2][2] = 1; 
        B.a[0][0] = a[n];
        B.a[1][0] = a[n - 1];
        B.a[2][0] = ans;
        for(int i = 0; i < 3; ++i) tmp.a[i][i] = 1;
        for(; k; k >>= 1, A = A * A) if(k & 1) tmp = tmp * A;
        B = tmp * B;
        printf("%lld
    ", (B.a[2][0] % mod + mod) % mod);
        return 0;
    }
    View Code
  • 相关阅读:
    git删除大文件
    正则表达式学习
    python小技巧集锦
    python的编译
    笔记本BIOS按键和启动项选择按键
    Ubuntu 不能识别U盘
    一文读懂Java 11的ZGC为何如此高效
    ELK原理与介绍
    使用uniapp之-在微信小程序内打开腾讯地图app或高德地图app
    使用Git多人协作开发时分支合并流程
  • 原文地址:https://www.cnblogs.com/19992147orz/p/7688705.html
Copyright © 2011-2022 走看看