zoukankan      html  css  js  c++  java
  • Codeforces 1182E Product Oriented Recurrence 矩阵快速幂

    Product Oriented Recurrence

    先化简原式子

    c ^ x * f[x]  = c ^ (x-1) * f[x-1] * c ^ (x-2) * f[x-2] * c ^ (x-3) * f[x-3]

    及g[x] = c ^ x * f[x]

    g[x] = g[x-1] * g[x-2] * g[x-3]

    然后用矩阵快速幂计算g1, g2, g3的贡献, 计算出gn 之后 转回 fn

    //#pragma GCC optimize(2)
    //#pragma GCC optimize(3)
    //#pragma GCC optimize(4)
    #include<bits/stdc++.h>
    #define LL long long
    #define LD long double
    #define ull unsigned long long
    #define fi first
    #define se second
    #define mk make_pair
    #define PLL pair<LL, LL>
    #define PLI pair<LL, int>
    #define PII pair<int, int>
    #define SZ(x) ((int)x.size())
    #define ALL(x) (x).begin(), (x).end()
    #define fio ios::sync_with_stdio(false); cin.tie(0);
    
    using namespace std;
    
    const int N = 1e5 + 7;
    const int inf = 0x3f3f3f3f;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9 + 7;
    const double eps = 1e-8;
    const double PI = acos(-1);
    
    template<class T, class S> inline void add(T &a, S b) {a += b; if(a >= mod) a -= mod;}
    template<class T, class S> inline void sub(T &a, S b) {a -= b; if(a < 0) a += mod;}
    template<class T, class S> inline bool chkmax(T &a, S b) {return a < b ? a = b, true : false;}
    template<class T, class S> inline bool chkmin(T &a, S b) {return a > b ? a = b, true : false;}
    
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    
    LL power(LL a, LL b) {
        LL ans = 1;
        while(b) {
            if(b & 1) ans = ans * a % mod;
            a = a * a % mod; b >>= 1;
        }
        return ans;
    }
    
    int MOD = (int)1e9 + 6;
    
    struct Matrix {
        int a[3][3];
        Matrix() {
            memset(a, 0, sizeof(a));
        }
        void init() {
            for(int i = 0; i < 3; i++) {
                a[i][i] = 1;
            }
        }
        Matrix operator * (const Matrix &B) const {
            Matrix C;
            for(int i = 0; i < 3; i++) {
                for(int j = 0; j < 3; j++) {
                    for(int k = 0; k < 3; k++) {
                        C.a[i][j] += 1LL * a[i][k] * B.a[k][j] % MOD;
                        if(C.a[i][j] >= MOD) C.a[i][j] -= MOD;
                    }
                }
            }
            return C;
        }
    
        Matrix operator ^ (LL b) {
            Matrix C; C.init();
            Matrix A = (*this);
            while(b) {
                if(b & 1) C = C * A;
                A = A * A; b >>= 1;
            }
            return C;
        }
    } M;
    
    int mat[3][3] {
        {1, 1, 1},
        {1, 0, 0},
        {0, 1, 0}
    };
    
    LL n, f1, f2, f3, c;
    
    int main() {
        for(int i = 0; i < 3; i++) {
            for(int j = 0; j < 3; j++) {
                M.a[i][j] = mat[i][j];
            }
        }
    
        scanf("%lld%lld%lld%lld%lld", &n, &f1, &f2, &f3, &c);
    
        Matrix ret = M ^ (n - 3);
    
        f1 = f1 * power(c, 1) % mod;
        f2 = f2 * power(c, 2) % mod;
        f3 = f3 * power(c, 3) % mod;
    
        LL ans = 1;
    
        LL cnt1 = ret.a[0][2];
        LL cnt2 = ret.a[0][1];
        LL cnt3 = ret.a[0][0];
    
    
        ans = ans * power(f1, cnt1) % mod;
        ans = ans * power(f2, cnt2) % mod;
        ans = ans * power(f3, cnt3) % mod;
    
    
        LL inv = power(power(c, n), mod - 2);
    
        ans = ans * inv % mod;
    
        printf("%lld
    ", ans);
    
        return 0;
    }
    
    /*
    */
  • 相关阅读:
    HDU2586 How far away?(tarjan的LCA)
    You Raise Me Up
    POJ2891 Strange Way to Express Integers(中国剩余定理)
    POJ2142 The Balance(扩展欧几里得)
    HDU 1166模仿大牛写的线段树
    NetWord Dinic
    HDU 1754 线段树裸题
    hdu1394 Minimum Inversion Number
    hdu2795 Billboard
    【完全版】线段树
  • 原文地址:https://www.cnblogs.com/CJLHY/p/11223481.html
Copyright © 2011-2022 走看看