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\n", res);
}
}
return 0;
}
E-MAZE_2019牛客暑期多校训练营(第二场)的更多相关文章
- 2019牛客暑期多校训练营(第二场) H-Second Large Rectangle(单调栈)
题意:给出由01组成的矩阵,求求全是1的次大子矩阵. 思路: 单调栈 全是1的最大子矩阵的变形,不能直接把所有的面积存起来然后排序取第二大的,因为次大子矩阵可能在最大子矩阵里面,比如: 1 0 0 1 ...
- 2020牛客暑期多校训练营 第二场 K Keyboard Free 积分 期望 数学
LINK:Keyboard Free 我要是会正经的做法 就有鬼了. 我的数学水平没那么高. 三个同心圆 三个动点 求围成三角形面积的期望. 不会告辞. 其实可以\(n^2\)枚举角度然后算出面积 近 ...
- 2020牛客暑期多校训练营 第二场 J Just Shuffle 置换 群论
LINK:Just Shuffle 比较怂群论 因为没怎么学过 置换也是刚理解. 这道题是 已知一个置换\(A\)求一个置换P 两个置换的关键为\(P^k=A\) 且k是一个大质数. 做法是李指导教我 ...
- 2020牛客暑期多校训练营 第二场 I Interval 最大流 最小割 平面图对偶图转最短路
LINK:Interval 赛时连题目都没看. 观察n的范围不大不小 而且建图明显 考虑跑最大流最小割. 图有点稠密dinic不太行. 一个常见的trick就是对偶图转最短路. 建图有点复杂 不过建完 ...
- 2020牛客暑期多校训练营 第二场 C Cover the Tree 构造 贪心
LINK:Cover the Tree 最受挫的是这道题,以为很简单 当时什么都想不清楚. 先胡了一个树的直径乱搞的贪心 一直过不去.后来意识到这类似于最经典长链剖分优化贪心的做法 然后那个是求最大值 ...
- 2020牛客暑期多校训练营 第二场 B Boundary 计算几何 圆 已知三点求圆心
LINK:Boundary 计算几何确实是弱项 因为好多东西都不太会求 没有到很精通的地步. 做法很多,先说官方题解 其实就是枚举一个点 P 然后可以发现 再枚举一个点 然后再判断有多少个点在圆上显然 ...
- 2020牛客暑期多校训练营 第二场 A All with Pairs 字符串hash KMP
LINK:All with Pairs 那天下午打这个东西的时候状态极差 推这个东西都推了1个多小时 (比赛是中午考试的我很困 没睡觉直接开肝果然不爽 一开始看错匹配的位置了 以为是\(1-l\)和\ ...
- 2019牛客暑期多校训练营(第九场) D Knapsack Cryptosystem
题目 题意: 给你n(最大36)个数,让你从这n个数里面找出来一些数,使这些数的和等于s(题目输入),用到的数输出1,没有用到的数输出0 例如:3 4 2 3 4 输出:0 0 1 题解: 认真想一 ...
- 2020牛客暑假多校训练营 第二场 H Happy Triangle set 线段树 分类讨论
LINK:Happy Triangle 这道题很容易. 容易想到 a+b<x a<x<b x<a<b 其中等于的情况在第一个和第三个之中判一下即可. 前面两个容易想到se ...
- 2020牛客暑假多校训练营 第二场 G Greater and Greater bitset
LINK:Greater and Greater 确实没能想到做法. 考虑利用bitset解决问题. 做法是:逐位判断每一位是否合法 第一位 就是 bitset上所有大于\(b_1\)的位置 置为1. ...
随机推荐
- win10虚拟机搭建Hadoop集群(已完结)
1 在虚拟机安装 Ubuntu 2 安装网络工具 Ubuntu最小化安装没有 ifconfig命令 sudo apt-get install net-tools 3 Ubuntu修改网卡名字 修改网卡 ...
- T-SQL 日期
--日期查询格式 ) --R:06/17/2011 ) --R:2011.06.17 ) --R:17/06/2011 ) --R:17.06.2011 ) --R:17-06-2011 ) --R: ...
- 【MySQL】添加多个字段
MySQL 遇到了添加多个字段的问题,尝试了几次,搞定了,记录下. 示例代码如下: alter table ad_data add ( exposure_count bigint(20) defaul ...
- 模拟器无Back、Menu等键
问题如图所示: 解决方法: 1. 打开Android Virtual Device (AVD) Manager --> 选择模拟器,并点击edit --> 勾选KeyBoard中的选项,并 ...
- JS 中获得根目录
/*** * 获得根目录 * @returns */ function getRootPath() { var strFullPath = window.document.location.href; ...
- Thread.Sleep太久,界面卡死
在Winform程序的UI界面使用Thread.Sleep,窗体界面会被卡死,如图1所示,程序sleep 5000毫秒,时间到了之后,按钮的名称才更改过来,窗体也能被鼠标拖动.而用Delay方法,就能 ...
- 前端面试 js 你有多了解call,apply,bind?
函数原型链中的 apply,call 和 bind 方法是 JavaScript 中相当重要的概念,与 this 关键字密切相关,相当一部分人对它们的理解还是比较浅显,所谓js基础扎实,绕不开这些基础 ...
- 微服务世界之Nacos初见
Nacos 1.概要 Dubbo 服务的注册和发现/rpc通信/负载均衡/限流/熔断/降级 Spring Cloud alibaba 服务注册发现中间件 zookeeper/eureka/consul ...
- .netcore持续集成测试篇之Xunit数据驱动测试一
系列目录 Nunit里提供了丰富的数据测试功能,虽然Xunit里提供的比较少,但是也能满足很多场景下使用了,如果数据场景非常复杂,Nunit和Xunit都是无法胜任的,有不少测试者选择自己编写一个数据 ...
- python环境的安装 环境变量和系统变量
一.python 的安装 python 2.7 和 python 3.6的安装(一路点点点就行) 在安装的时候注意一下红框的内容,意思代表将其添加到环境变量中 环境变量是在操作系统中一个具有特定名字的 ...