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

  • 相关阅读:
    表变量和临时表的比较
    表变量和临时表
    微信小程序(五)
    微信小程序(四)开发框架
    微信小程序(三)开发框架
    微信小程序(二)
    微信小程序(一)
    菜鸡的Java笔记第二
    C#中的委托和事件
    在GridView控件里面绑定DropDownList控件
  • 原文地址:https://www.cnblogs.com/Inko/p/11616854.html
Copyright © 2011-2022 走看看