zoukankan      html  css  js  c++  java
  • 2012-2013 ACM-ICPC, Asia Tokyo Regional Contest

    https://codeforces.com/gym/101412

    C - One-Dimensional Cellular Automaton

    签到题,就是直接矩阵快速幂,一开始用longlong然后到处取模导致T了一发,卡常之后才过。

    测出来了,取模大概是11倍常数,鉴于大概元素的范围是2^16次方,所以认为取模是近似一个log是可以的,毕竟本质是移位和乘法和加法神奇的编译器除法优化。就算乘法也是并行的,那也是几倍常数,而且假如不开O2就直接是除法和减法,这就完蛋了。

    所以说矩阵的模板要设置上限n,特别是多组数据的那种,不要每次都MAXN。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
     
    int mod;
     
    struct Matrix {
        static const int MAXN = 50;
        int ma[MAXN][MAXN], n;
        Matrix(int _n) {
            n = _n;
            init();
        }
        void init() {
            memset(ma, 0, sizeof(ma));
        }
        void setE() {
            init();
            for(int i = 0; i < n; ++i)
                ma[i][i] = 1;
        }
        Matrix operator*(const Matrix &x)const {
            Matrix res(x.n);
            for(int k = 0; k < n; ++k) {
                for(int i = 0; i < n; ++i) {
                    register int r = ma[i][k];
                    for(int j = 0; j < n; ++j)
                        res.ma[i][j] += r * x.ma[k][j];
                }
            }
            for(int i = 0; i < n; ++i) {
                for(int j = 0; j < n; ++j)
                    res.ma[i][j] %= mod;
            }
            return res;
        }
    };
     
    Matrix qpow(Matrix x, ll n) {
        Matrix res(x.n);
        res.setE();
        while(n) {
            if(n & 1)
                res = res * x;
            x = x * x;
            n >>= 1;
        }
        return res;
    }
     
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
    #endif // Yinku
        int n, m, a, b, c, t;
        while(~scanf("%d%d%d%d%d%d", &n, &m, &a, &b, &c, &t)) {
            if(n == 0 && m == 0 && a == 0 && b == 0 && c == 0 && t == 0)
                break;
            mod = m;
     
            Matrix F(n), A(n);
            for(int i = 0; i < n; ++i)
                scanf("%d", &F.ma[i][0]);
     
            for(int i = 0; i < n; ++i) {
                if(i - 1 >= 0)
                    A.ma[i][i - 1] = a;
                A.ma[i][i] = b;
                if(i + 1 < n)
                    A.ma[i][i + 1] = c;
            }
            A = qpow(A, t);
            F = A * F;
            for(int i = 0; i < n; ++i)
                printf("%d%c", F.ma[i][0], " 
    "[i == n - 1]);
        }
    }
    

    D - Find the Outlier

  • 相关阅读:
    383. Ransom Note
    598. Range Addition II
    453. Minimum Moves to Equal Array Elements
    492. Construct the Rectangle
    171. Excel Sheet Column Number
    697. Degree of an Array
    665. Nondecreasing Array
    视频网站使用H265编码能提高视频清晰度吗?
    现阶段的语音视频通话SDK需要解决哪些问题?
    企业远程高清会议平台视频会议系统在手机端使用的必备要求有哪些?
  • 原文地址:https://www.cnblogs.com/Inko/p/11616854.html
Copyright © 2011-2022 走看看