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;
    }
    
  • 相关阅读:
    算法题:单调递增的数字
    算法题:搜索旋转排序数组
    算法题:K个一组翻转链表
    django错误
    virtualenvwrapper出错
    谷歌浏览器css样式不显示问题
    Python爬取豆瓣电子书信息
    flask secret key的作用
    【Hibernate】--实体状体与主键生成策略
    【Struts2+Spring3+Hibernate3】SSH框架整合实现CRUD_1.3
  • 原文地址:https://www.cnblogs.com/bpdwn-cnblogs/p/11249275.html
Copyright © 2011-2022 走看看