【2019牛客暑期多校训练营(第二场)- E】MAZE(线段树优化dp,dp转矩阵乘法,线段树维护矩阵乘法)

题干:

链接:https://ac.nowcoder.com/acm/contest/882/E?&headNav=acm
来源:牛客网
 

Given a maze with N rows and M columns, where bijb_{ij}bij​ represents the cell on the i-row, j-th column. If bi,j="1"b_{i, j} = \texttt{"1"}bi,j​="1", it's a wall and can't not be passed. If you are on the cell bi,jb_{i, j}bi,j​, you can go to b(i+1),jb_{(i+1), j}b(i+1),j​, bi,(j−1)b_{i, (j-1)}bi,(j−1)​, or bi,(j+1)b_{i, (j+1)}bi,(j+1)​ as long as it's not a wall.

Sometime, a cell may be changed into wall, or vise versa. You need to find out the number of way to pass through the maze starting at some given cell and finishing at some given cell.

 

If the starting cell or finishing cell is a wall, there's clearly no way to pass through the maze.

Note that you can't go back to the cell you just from.

示例1

输入

复制

2 2 3
00
00
2 1 2
1 1 2
2 1 2

输出

复制

2
1

题目大意:

有一个 n*m 的 01 矩阵,1 表示不可行,0 代表可行;

每次可以从 (i, j) 走到 (i, j – 1),(i, j + 1) 和 (i + 1, j),且不能回到已走过的格子;

有 q 个以下两种操作:

1、将某个格子的状态反转,即1变0,0变1

2、询问从 (1, x) 走到 (n, y) 的方案数。

1 <= n,q <= 5e4,1 <= m <= 10。

解题报告:

先考虑不带修改的版本,设矩阵第 i 行第 j 个元素为 A[i][j];

dp[i][j] 表示从第 i – 1 行经过 (i – 1, j) 走到 (i, j) 的方案数,状态转移方程如下:

简单来说,dp[i][j] 等于 A[i – 1, j] 向左和向右 A[i – 1][k] 都等于 0 的那些 dp[i – 1][k] 的和;

如当 n = 2,m = 6 时:(最上面为第一行)

000100
101010

dp[2][2] = dp[1][1] + dp[1][2] + dp[1][3];

dp[2][4] = 0

dp[2][6] = dp[1][5] + dp[1][6]。

dp[2]的其余值都是0。

因此第 i 行的 dp 值到第 i + 1 行的 dp 值的转移可用矩阵 Mi 实现;

如上图第一行的 dp 值到第二行 dp 值的转移矩阵 M1:

(注意就算是a[i][j]==1,但是也要更新这一个值,但是其实并没有什么用,因为后面也会被continue掉)

111000
111000
111000
000000
000011
000011

那么要求从 (1, x) 走到 (n, y) 的方案数,即令 dp[1][x] = 1,求 dp[n + 1][y];

为什么是 dp[n + 1][y] 而不是 dp[n][y],因为 dp[n][y] 设定状态的时候,表示的就是从第 n – 1 行经过 (n – 1, y) 走到 (n, y) 的方案数,故意的漏掉那些从第 n 行走到 (n, y) 的方案数,这样做的目的也是便于直接统计,而 dp[n + 1][y] 则表示从第 n 行经过 (n, y) 的所有方案数,也就是我们要的答案了。

那么让矩阵M[i][j]代表的含义是从第i列走到第j列的方案数。

若令矩阵ans = M_1 \times M_2 \times M_3 \times ... \times M_n,则ans[x][y]就是答案。

再考虑带修改的版本;

因为每次都会修改一个点,也就是每次只会修改N个矩阵中的一个矩阵,然后再求矩阵的和。

因为矩阵乘法具有可交换性质,所以可以用线段树维护矩阵乘积:M_1 \times M_2 \times M_3 \times ... \times M_n,反转 (x, y) 的操作即重构 M_x,为单点修改,时间复杂度为 O(m^3logn);

根节点维护的就是 M_1 \times M_2 \times M_3 \times ... \times M_n,可 O(1) 回答询问,总时间复杂度 O(m^3logn)。

注意实现的细节,你如果在结构体中加上l和r节点的话,那矩阵最好重新定义一个结构体,不然的话你pushup就要多写两行。如果不多这几行的话显然是不对的。(因为你的l和r就被冲掉了)

再贴一个别人的题解:

这样的话就可以理解为,对于每一个查询只有dp[1][x]是1,dp[1]的其他值都是0,然后求dp[n+1][y],

所以就是=(0,0,,,第x位上是1,,0) * 构造的矩阵的第四列,也就是构造的矩阵的M[x][y]项。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define FF first
#define SS second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 50005 + 5;
const ll mod = 1e9 + 7;
int n,m,q;
struct TREE {int l,r;ll m[12][12];
} tr[MAX<<2];
int a[MAX][13];
TREE mul(TREE a,TREE b) {TREE c;for(int i = 1; i<=m; i++) {for(int j = 1; j<=m; j++) {c.m[i][j] = 0;for(int k = 1; k<=m; k++) {c.m[i][j] = (c.m[i][j] + (a.m[i][k]*b.m[k][j])%mod) % mod;}}}return c;
} 
void modify(int cur,int x) {memset(tr[cur].m,0,sizeof tr[cur].m);for(int i = 1; i<=m; i++) {if(a[x][i] == 1) continue;tr[cur].m[i][i]=1;for(int j = i-1; j>=1&&a[x][j]==0; j--) tr[cur].m[i][j] = 1;for(int j = i+1; j<=m&&a[x][j]==0; j++) tr[cur].m[i][j] = 1;}
}void pushup(int cur) {int l = tr[cur].l,r = tr[cur].r;tr[cur] = mul(tr[cur*2],tr[cur*2+1]);tr[cur].l = l,tr[cur].r = r;
}
void build(int l,int r,int cur) {tr[cur].l = l,tr[cur].r = r;if(l == r) {modify(cur,l);return;}int m = (l+r)>>1;build(l,m,cur*2);build(m+1,r,cur*2+1);pushup(cur); 
}
void update(int tar,int cur) {if(tr[cur].l == tr[cur].r) {modify(cur,tr[cur].l); return;}int mid = (tr[cur].l + tr[cur].r)>>1;if(tar <= mid) update(tar,cur*2);else update(tar,cur*2+1);pushup(cur); 
}
int main()
{cin>>n>>m>>q;for(int i = 1; i<=n; i++) {for(int j = 1; j<=m; j++) scanf("%1d",&a[i][j]);}build(1,n,1);while(q--) {int op,x,y;scanf("%d%d%d",&op,&x,&y);if(op == 1) a[x][y] ^= 1,update(x,1);else printf("%lld\n",tr[1].m[x][y]%mod);}return 0 ;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/439899.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Apollo进阶课程⑰丨Apollo感知之旅——传感器选择和安装

目录 1.激光雷达 2.相机 3.Radar毫米波 4.安装传感器 原文链接&#xff1a;进阶课程⑰丨Apollo感知之旅——传感器选择和安装 上周阿波君为大家详细介绍了「进阶课程⑯ Apollo感知之旅——感知概况」。 传感器是一种检测装置&#xff0c;能感受到被测量的信息&#xff0c;…

一步步编写操作系统 14 CPU与外设通信——IO接口 上

介绍显卡之前&#xff0c;必须得和大家交待清楚&#xff0c;那么多的外部设备&#xff0c;cpu是如何与他们交流。 大家都学过微机接口技术吧&#xff1f;没学过也没关系&#xff0c;反正我也只是笼统地说说^_^&#xff0c;保证大家一定能看得懂。 按理说&#xff0c;如果硬件…

2.2)深度学习笔记:优化算法

目录 1&#xff09;Mini-batch gradient descent&#xff08;重点&#xff09; 2&#xff09;Understanding mini-batch gradient descent 3&#xff09;Exponentially weighted averages 4&#xff09;Understanding exponetially weighted averages 5&#xff09;Bias c…

【POJ - 2019】Cornfields(二维st表,模板)

题干&#xff1a; FJ has decided to grow his own corn hybrid in order to help the cows make the best possible milk. To that end, hes looking to build the cornfield on the flattest piece of land he can find. FJ has, at great expense, surveyed his square fa…

虚拟机安装Linux(vmware + ubuntu)

VMWare 提取码&#xff1a;7zph 建议官网下载比较新&#xff0c;还快一点 https://www.vmware.com/products/workstation-pro.htmlubantu 下载地址 安装过程都差不多可以参考 VMware下安装Ubuntu系统图文详细教程_master-CSDN博客_vmware安装ubuntu系统 出现蓝屏问题可以参考…

Apollo进阶课程⑱丨Apollo感知之旅——传感器标定

目录 传感器标定 标定的目的 传感器标定算法 标定案例解析 3D标定间制作 Cmaera-to-Camera外参标定 Lidar-to-Camera外参标定 Lidar-to-Lidar外参标定 Lidar内参标定 Lidar-to-GPS外参标定 自然场景的Lidar-to-Camera外参标定 自然场景的Bifocal Camera外参标定 C…

一步步编写操作系统 15 CPU与外设通信——IO接口,下

既然都说到IO接口了&#xff0c;不知道各位有没有疑问&#xff0c;cpu是怎样访问到IO接口呢&#xff1f;肯定得有个链路吧&#xff1f;什么&#xff1f;有隐约听到有同学开玩笑说&#xff1a;cpu用无线访问其它设备。哈哈&#xff0c;不知道各位听说过没有&#xff0c;无线的终…

Telnet端口连接Linux服务器失败

在ubuntu写了个服务器端口号是666 &#xff0c;ip地址是192.168.96.129 在windows用telnet无法连接上 首先检查windows telnet服务是否打开 Windows 10操作系统上使用telnet命令&#xff08;图文&#xff09;_时间-CSDN博客_windows使用telnet命令 测试网络是否通&#xff1a;…

*【2019牛客暑期多校训练营(第三场)- G】Removing Stones(分治)

题干&#xff1a; 链接&#xff1a;https://ac.nowcoder.com/acm/contest/883/G 来源&#xff1a;牛客网 Summer vacation is coming and Mark has returned home from his university having successfully survived the exam week. Today, he is very bored. So his frien…

重磅 | 完备的 AI 学习路线,最详细的资源整理!

本文转自微信公众号&#xff1a;Datawhale&#xff08;强烈推荐&#xff09; 原创&#xff1a; AIUnion Datawhale 今天 【导读】 本文由知名开源平台&#xff0c;AI技术平台以及领域专家&#xff1a;Datawhale&#xff0c;ApacheCN&#xff0c;AI有道和黄海广博士联合整理贡献…

一步步编写操作系统 16 显卡概述

之前我们的mbr中我们刚刚向屏幕输出了“1 MBR”这几个字符&#xff0c;这种喜悦还没有过去&#xff0c;我就要给大家泼冷水了&#xff1a;这种打印字符的方法马上就用不了啦。 mbr是运行在实模式下&#xff0c;所以在实模式下也可以用bios的0x10中断打印字符串&#xff0c;这是…

Windows/Linux 下使用telnet发送消息

Windows下使用telnet 1.首先打开cmd命令行连接上服务器端口 连不上可以参考这篇 Telnet端口连接Linux服务器失败_m0_46480482的博客-CSDN博客 telnnt <ip地址> <端口号> 2. 连接成功后&#xff0c;会发现是一片黑的 按住 ctrl ] 可以招出提示 输入 &#x…

【2019牛客暑期多校训练营(第六场)- D】Move(随机化二分)

题干&#xff1a; 链接&#xff1a;https://ac.nowcoder.com/acm/contest/886/D 来源&#xff1a;牛客网 After the struggle of graduating from college, TangTang is about to move from a student apartment to his new home. TangTang has n items to move, the i-th …

Apollo进阶课程⑲丨Apollo感知之旅——感知算法

目录 点云感知 启发式方法&#xff1a;NCut 深度学习方法&#xff1a;CNNSeg 视觉感知 CNN检测 CNN分割 后处理 红绿灯感知 基于深度学习的红绿灯感知模块 Radar感知 超声波感知 原文链接&#xff1a;进阶课程⑲丨Apollo感知之旅——感知算法 感知是自动驾驶的第一环…

一步步编写操作系统 17 显存,显卡,显示器 上

为了能够看到图像&#xff0c;我们需要显示器。无论是哪种显示器&#xff0c;它都是由显卡来控制的&#xff0c;我们没必要了解液晶显示器和普通CRT显示器的差别。无底是哪种显卡&#xff0c;它提供给我们的可编程接口都是一样的&#xff1a;IO端口和显存。 显存是由显卡提供的…

C++ socket网络编程笔记(服务端1)

1. 创建一个信箱 int sock; // 创建一个信箱 sock socket(AF_INT,SOCK_STREAM,0) 2. 创建一个标签&#xff0c;写上地址和端口号 struct sockaddr_in server_addr; // 创建一个标签server_addr.sin_family AF_INET; // 标签--协议族 (AF_INET表示IPV4)ser…

动手学PaddlePaddle(0):新版本PaddlePaddle安装

目录 0.引言 1.环境 2.Windows下安装 安装Python 安装PaddlePaddle 0.引言 今天介绍如何安装新版本的PaddlePaddle&#xff0c;现在最新版的PaddlePaddle是指Fluid版&#xff0c;Fluid可以让用户像Pytorch和TensorFlow Eager Execution一样执行程序&#xff0c;也就是说P…

一步步编写操作系统 18 操作显卡,显存,显示器 下

接上回&#xff0c;大家看下显卡各种模式的内存分布。 各外部设备都是通过软件指令的形式与上层接口通信的&#xff0c;显卡&#xff08;显示适配器&#xff09;也不例外&#xff0c;所以它也有自己的bios。位置是0xC0000到0xC7FFF。显卡支持三种模式&#xff0c;文本模式、黑白…

【2019牛客暑期多校训练营(第六场)- J】Upgrading Technology(dp)

题干&#xff1a; 链接&#xff1a;https://ac.nowcoder.com/acm/contest/886/J?&headNavacm&headNavacm&headNavacm&headNavacm 来源&#xff1a;牛客网 Rowlet is playing a very popular game in the pokemon world. Recently, he has encountered a p…

VMware 安装VMware Tools

想要在linux和windows之间复制粘贴&#xff0c;把之前一直没有下的vmwaretools的下载过程记录一下。 1.左上角菜单 ->虚拟机 ->安装 vmware tools (我已经点过了所以是取消安装) 2.桌面多了一个VMware tools &#xff0c;点进去看一下位置&#xff0c;复制一下tar.gz的文…