• 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

  • 相关阅读:
    关于用户、用户组及文件权限的试题
    lvm-简介
    项目中用到的jar包简介(1)
    Centos7开启SSH服务
    2.docker架构,原理,安装及简单应用
    如何平滑将注册中心从Eureka迁移到Nacos?
    8.k8s连载--重新生成k8s token(kubeadm join报错及解决)
    7. 复制k8s Node节点 并重新初始化k8s-nodes2节点 (k8s连载)
    6. k8s + jenkins 实现持续集成(完)
    5.k8s基本命令汇总
  • 原文地址:https://www.cnblogs.com/Inko/p/11616854.html
Copyright © 2020-2023  润新知