zoukankan      html  css  js  c++  java
  • E-MAZE_2019牛客暑期多校训练营(第二场)

    题意

    给出n行m列的迷宫0可走1不可走,有两个操作,操作1变换点(a,b)的值,操作2查询(1,a)到(n,b)的方案数

    题解

    (F[i][j])为第i-1行到达第i行第j列的方案数,若点((i,j))上下为0的可延伸范围为((l,r)),则(F[i][j] = sum_{k=l}^r F[i-1][k])
    由这个式子就可以构造出第i-1行到第i行方案数的转移矩阵,用线段树维护一下区间矩阵乘积

    代码

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <bitset>
    
    using namespace std;
    typedef long long ll;
    const int mx = 5e4+5;
    const int mod = 1e9+7;
    char mp[mx][12];
    int n, m, q;
    
    struct Matrix {
        ll a[12][12];
        Matrix() {memset(a, 0, sizeof(a));}
        Matrix(int op) {
            memset(a, 0, sizeof(a));
            for (int i = 1; i <= m; i++) a[i][i] = 1;
        }
        Matrix operator * (Matrix other) const{
            Matrix tmp = Matrix();
            for (int i = 1; i <= m; i++) {
                for (int j = 1; j <= m; j++) {
                    for (int k = 1; k <= m; k++) {
                        tmp.a[i][j] += a[i][k] * other.a[k][j] % mod;
                        tmp.a[i][j] %= mod;
                    }
                }
            }
            return tmp;
        }
    }mat[mx<<2];
    
    void pushUp(int rt) {
        mat[rt] = mat[rt<<1] * mat[rt<<1|1];
    }
    
    void InitData(int pos, int rt) {
        mat[rt] = Matrix();
        for (int i = 1; i <= m; i++) {
            for (int j = i; j <= m && mp[pos][j] == '0'; j++) {
                mat[rt].a[j][i] = 1;
            }
            for (int j = i; j >= 1 && mp[pos][j] == '0'; j--) {
                mat[rt].a[j][i] = 1;
            }
        }
    }
    
    void build(int l, int r, int rt) {
        if (l == r) {
            if (r == 1) mat[rt] = Matrix(0);
            else InitData(r, rt);
            return;
        }
        int mid = (l + r) / 2;
        build(l, mid, rt<<1);
        build(mid+1, r, rt<<1|1);
        pushUp(rt);
    }
    
    void update(int pos, int l, int r, int rt) {
        if (pos == 1) return;
        if (l == pos && r == pos) {
            InitData(pos, rt);
            return;
        }
        int mid = (l + r) / 2;
        if (pos <= mid) update(pos, l, mid, rt<<1);
        else update(pos, mid+1, r, rt<<1|1);
        pushUp(rt);
    }
    
    int main() {
        scanf("%d%d%d", &n, &m, &q);
        for (int i = 1; i <= n; i++) scanf("%s", mp[i]+1);
        build(1, n, 1);
        while (q--) {
            int op, a, b;
            scanf("%d%d%d", &op, &a, &b);
            if (op == 1) {
                mp[a][b] = (mp[a][b] == '1' ? '0' : '1');
                update(a, 1, n, 1);
            } else {
                Matrix ans = mat[1];
                int s[12] = {0};
                for (int i = a; i <= m && mp[1][i] == '0'; i++) s[i] = 1;
                for (int i = a; i >= 1 && mp[1][i] == '0'; i--) s[i] = 1;
    
                ll res = 0;
                for (int i = 1; i <= m; i++) {
                    res += s[i] * ans.a[i][b];
                    res %= mod;
                }
                printf("%lld
    ", res);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    和2018年年初做管理系统的不同(vuex)
    项目中使用package-lock.json锁版本问题
    沟通协作:避免犯低级错误,开发前沟通清楚所有细节
    学会学习:高效学习方式(使用vscode-snippet有感)
    关于学习,避免没必要的熬夜的思考
    pc端布局的一点思考
    学习掌握一个新东西
    要想有价值,首先要乐于去解决每一个问题
    problem: 记一次聊天框的表情包弹框不显示的找问题过程
    abp-159,js最理想的继承——寄生组合式继承
  • 原文地址:https://www.cnblogs.com/bpdwn-cnblogs/p/11249275.html
Copyright © 2011-2022 走看看