题意

给出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行方案数的转移矩阵,用线段树维护一下区间矩阵乘积

代码

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <queue>
  5. #include <bitset>
  6. using namespace std;
  7. typedef long long ll;
  8. const int mx = 5e4+5;
  9. const int mod = 1e9+7;
  10. char mp[mx][12];
  11. int n, m, q;
  12. struct Matrix {
  13. ll a[12][12];
  14. Matrix() {memset(a, 0, sizeof(a));}
  15. Matrix(int op) {
  16. memset(a, 0, sizeof(a));
  17. for (int i = 1; i <= m; i++) a[i][i] = 1;
  18. }
  19. Matrix operator * (Matrix other) const{
  20. Matrix tmp = Matrix();
  21. for (int i = 1; i <= m; i++) {
  22. for (int j = 1; j <= m; j++) {
  23. for (int k = 1; k <= m; k++) {
  24. tmp.a[i][j] += a[i][k] * other.a[k][j] % mod;
  25. tmp.a[i][j] %= mod;
  26. }
  27. }
  28. }
  29. return tmp;
  30. }
  31. }mat[mx<<2];
  32. void pushUp(int rt) {
  33. mat[rt] = mat[rt<<1] * mat[rt<<1|1];
  34. }
  35. void InitData(int pos, int rt) {
  36. mat[rt] = Matrix();
  37. for (int i = 1; i <= m; i++) {
  38. for (int j = i; j <= m && mp[pos][j] == '0'; j++) {
  39. mat[rt].a[j][i] = 1;
  40. }
  41. for (int j = i; j >= 1 && mp[pos][j] == '0'; j--) {
  42. mat[rt].a[j][i] = 1;
  43. }
  44. }
  45. }
  46. void build(int l, int r, int rt) {
  47. if (l == r) {
  48. if (r == 1) mat[rt] = Matrix(0);
  49. else InitData(r, rt);
  50. return;
  51. }
  52. int mid = (l + r) / 2;
  53. build(l, mid, rt<<1);
  54. build(mid+1, r, rt<<1|1);
  55. pushUp(rt);
  56. }
  57. void update(int pos, int l, int r, int rt) {
  58. if (pos == 1) return;
  59. if (l == pos && r == pos) {
  60. InitData(pos, rt);
  61. return;
  62. }
  63. int mid = (l + r) / 2;
  64. if (pos <= mid) update(pos, l, mid, rt<<1);
  65. else update(pos, mid+1, r, rt<<1|1);
  66. pushUp(rt);
  67. }
  68. int main() {
  69. scanf("%d%d%d", &n, &m, &q);
  70. for (int i = 1; i <= n; i++) scanf("%s", mp[i]+1);
  71. build(1, n, 1);
  72. while (q--) {
  73. int op, a, b;
  74. scanf("%d%d%d", &op, &a, &b);
  75. if (op == 1) {
  76. mp[a][b] = (mp[a][b] == '1' ? '0' : '1');
  77. update(a, 1, n, 1);
  78. } else {
  79. Matrix ans = mat[1];
  80. int s[12] = {0};
  81. for (int i = a; i <= m && mp[1][i] == '0'; i++) s[i] = 1;
  82. for (int i = a; i >= 1 && mp[1][i] == '0'; i--) s[i] = 1;
  83. ll res = 0;
  84. for (int i = 1; i <= m; i++) {
  85. res += s[i] * ans.a[i][b];
  86. res %= mod;
  87. }
  88. printf("%lld\n", res);
  89. }
  90. }
  91. return 0;
  92. }

E-MAZE_2019牛客暑期多校训练营(第二场)的更多相关文章

  1. 2019牛客暑期多校训练营(第二场) H-Second Large Rectangle(单调栈)

    题意:给出由01组成的矩阵,求求全是1的次大子矩阵. 思路: 单调栈 全是1的最大子矩阵的变形,不能直接把所有的面积存起来然后排序取第二大的,因为次大子矩阵可能在最大子矩阵里面,比如: 1 0 0 1 ...

  2. 2020牛客暑期多校训练营 第二场 K Keyboard Free 积分 期望 数学

    LINK:Keyboard Free 我要是会正经的做法 就有鬼了. 我的数学水平没那么高. 三个同心圆 三个动点 求围成三角形面积的期望. 不会告辞. 其实可以\(n^2\)枚举角度然后算出面积 近 ...

  3. 2020牛客暑期多校训练营 第二场 J Just Shuffle 置换 群论

    LINK:Just Shuffle 比较怂群论 因为没怎么学过 置换也是刚理解. 这道题是 已知一个置换\(A\)求一个置换P 两个置换的关键为\(P^k=A\) 且k是一个大质数. 做法是李指导教我 ...

  4. 2020牛客暑期多校训练营 第二场 I Interval 最大流 最小割 平面图对偶图转最短路

    LINK:Interval 赛时连题目都没看. 观察n的范围不大不小 而且建图明显 考虑跑最大流最小割. 图有点稠密dinic不太行. 一个常见的trick就是对偶图转最短路. 建图有点复杂 不过建完 ...

  5. 2020牛客暑期多校训练营 第二场 C Cover the Tree 构造 贪心

    LINK:Cover the Tree 最受挫的是这道题,以为很简单 当时什么都想不清楚. 先胡了一个树的直径乱搞的贪心 一直过不去.后来意识到这类似于最经典长链剖分优化贪心的做法 然后那个是求最大值 ...

  6. 2020牛客暑期多校训练营 第二场 B Boundary 计算几何 圆 已知三点求圆心

    LINK:Boundary 计算几何确实是弱项 因为好多东西都不太会求 没有到很精通的地步. 做法很多,先说官方题解 其实就是枚举一个点 P 然后可以发现 再枚举一个点 然后再判断有多少个点在圆上显然 ...

  7. 2020牛客暑期多校训练营 第二场 A All with Pairs 字符串hash KMP

    LINK:All with Pairs 那天下午打这个东西的时候状态极差 推这个东西都推了1个多小时 (比赛是中午考试的我很困 没睡觉直接开肝果然不爽 一开始看错匹配的位置了 以为是\(1-l\)和\ ...

  8. 2019牛客暑期多校训练营(第九场) D Knapsack Cryptosystem

    题目 题意: 给你n(最大36)个数,让你从这n个数里面找出来一些数,使这些数的和等于s(题目输入),用到的数输出1,没有用到的数输出0 例如:3  4 2 3 4 输出:0 0 1 题解: 认真想一 ...

  9. 2020牛客暑假多校训练营 第二场 H Happy Triangle set 线段树 分类讨论

    LINK:Happy Triangle 这道题很容易. 容易想到 a+b<x a<x<b x<a<b 其中等于的情况在第一个和第三个之中判一下即可. 前面两个容易想到se ...

  10. 2020牛客暑假多校训练营 第二场 G Greater and Greater bitset

    LINK:Greater and Greater 确实没能想到做法. 考虑利用bitset解决问题. 做法是:逐位判断每一位是否合法 第一位 就是 bitset上所有大于\(b_1\)的位置 置为1. ...

随机推荐

  1. windows下用easybcd引导ubuntu出现grub的解决方案

    linux安装时吧boot挂在到单独的分区 如果grub覆盖了mbr的话可以用pe工具箱修复windows的mbr linux引导项选grub 驱动器选安装时挂载了/boot的分区 添加条目 启动即可 ...

  2. ubuntu中设置python默认版本

    看/usr/bin中的Python文件,发现该文件是python2.7的链接文件 于是直接删掉这个软链接,然后重新创建python2.6的链接文件: 1 rm /usr/bin/python 2 ln ...

  3. 在vue中监听storage的变化

    1.首先在main.js中给Vue.protorype注册一个全局方法,其中,我们约定好了想要监听的sessionStorage的key值为’watchStorage’,然后创建一个StorageEv ...

  4. html的一些基本语法学习与实战

    其实在学校前端开始之前,问过自己为什么要学,因为自己学的比较杂,直到现在刚刚毕业出来工作了,才明确了方向了,要往嵌入式方向走,但是随着时代的发展,在编程和智能硬件结合的越来越紧密,特别是物联网这一块, ...

  5. 夯实Java基础(一)——数组

    1.Java数组介绍 数组(Array):是多个相同类型元素按一定顺序排列的集合. 数组是编程中最常见的一种数据结构,可用于存储多个数据,每个数组元素存放一个数据,通常我们可以通过数组元素的索引来访问 ...

  6. Spring Cloud微服务接口这么多怎么调试

    导读 我们知道在微服务架构下,软件系统会被拆分成很多个独立运行的服务,而这些服务间需要交互通信,就需要定义各种各样的服务接口.具体来说,在基于Spring Cloud的微服务模式中,各个微服务会基于S ...

  7. SpringBoot 使用JPA时解决no session的方法

    1.在application.yml中添加 spring.jpa.open-in-view: true 2.在使用查询的方法添加 @Transactional

  8. 消息中间件-activemq安全机制

    activemq作为消息中间件这样一个独立的个体存在,连通用户和服务器.如果没有一套完备的安全机制去设置用户权限设置消息分发机制可想后果是非常严重.ActiveMQ如果不加入安全机制的话,任何人只要知 ...

  9. 基于 WPF 模块化架构下的本地化设计实践

    背景描述 最近接到一个需求,就是要求我们的 WPF 客户端具备本地化功能,实现中英文多语言界面.刚开始接到这个需求,其实我内心是拒绝的的,但是没办法,需求是永无止境的.所以只能想办法解决这个问题. 首 ...

  10. 洛谷 P4344 [SHOI2015]脑洞治疗仪

    题意简述 维护序列,支持以下操作: 0 l r:将l~r赋为0 1 l1 r1 l2 r2:将l1~r1中的1替换l2~r2中的0,多余舍弃 2 l r:询问l~r中最大连续1的长度 题解思路 珂朵莉 ...