[2019牛客多校第二场][E. MAZE]
题目链接:https://ac.nowcoder.com/acm/contest/882/E
题目大意:有一个\(n\times m\)的01矩阵,一开始可以从第一行的一个点出发,每次可以向左、向右、向下移动一格且不能回头。中途会有一些点变为障碍物(用1表示),或者从障碍物变回可以通过的格子,同时还需要处理询问:从\((1,a)\)出发,走到\((n,b)\)的方案数有多少种。\(n\leq 50000,\ m\leq 10\)
题解:设\(f(i,j)\)为走到\((i,j)\)的方案数,且第\(i\)行里包含点\((i,j)\)的区间为\([l,r]\),则有\(f(i,j)=\sum_{k=l}^{r}f(i-1,k)\),这里的\(k\)就代表着从前一行的第\(k\)列走下来。可以发现这个转移方程可以转换成一个矩阵形式,即\((f(i,1),f(i,2),...,f(i,m))=(f(i-1,1),f(i-1,2),...,f(i-1,m))\cdot A\)其中\(A\)为状态转移矩阵。求从第\(i-1\)行到第\(i\)行的转移矩阵是可以用\(O(m^2)\)的时间复杂度来实现的。而最后一行的答案就是第一行的状态矩阵乘上这\(n\)行转移矩阵的乘积。在本题中,由于给出了起点和终点,所以若设这\(n\)行转移矩阵的乘积为\(A\),则答案就是\(A(a,b)\)。用线段树维护每行的矩阵以及区间的矩阵乘积即可。
#include<bits/stdc++.h>
using namespace std;
#define N 50001
#define LL long long
#define MOD 1000000007
LL n,m,q,op,x,y,a[N][];
struct Matrix
{
LL n,m;
LL f[][];
void init(LL nn,LL mm)
{
n=nn,m=mm;
for(LL i=;i<=n;i++)
for(LL j=;j<=m;j++)
f[i][j]=;
}
void set_E(LL nn)
{
n=m=nn;
for(LL i=;i<=n;i++)
for(LL j=;j<=n;j++)
f[i][j]=i==j;
}
Matrix operator *(const Matrix &t)const
{
Matrix res;
res.init(n,t.m);
for(LL i=;i<=n;i++)
for(LL j=;j<=t.m;j++)
for(LL k=;k<=m;k++)
(res.f[i][j]+=f[i][k]*t.f[k][j]%MOD)%=MOD;
return res;
}
void get(LL i,LL mm)
{
init(mm,mm);
LL l=,r=;
for(LL j=;j<=m;j++)
{
if(a[i][j]==)
{
l=r=j+;
continue;
}
while(r<=m && a[i][r]==a[i][l])r++;r--;
for(LL k=l;k<=r;k++)
f[k][j]++;
}
}
};
struct Segment_Tree
{
struct rua
{
LL l,r;
Matrix v;
}t[N<<];
void Update(LL x)
{
t[x].v=t[x*].v*t[x*+].v;
}
void Build(LL l,LL r,LL x)
{
t[x].l=l,t[x].r=r;
if(l==r)
{
t[x].v.get(l,m);
return;
}
LL mid=l+r>>;
Build(l,mid,x*);
Build(mid+,r,x*+);
Update(x);
}
void Change(LL x,LL y)
{
LL l=t[x].l,r=t[x].r;
LL mid=l+r>>;
if(l==y && y==r)
{
t[x].v.get(y,m);
return;
}
if(y<=mid)Change(x*,y);
else Change(x*+,y);
Update(x);
}
Matrix Query(LL L,LL R,LL x)
{
LL l=t[x].l,r=t[x].r;
LL mid=l+r>>;
if(L<=l && r<=R)return t[x].v;
Matrix res;
res.set_E(m);
if(L<=mid)res=res*Query(L,R,x*);
if(R>mid)res=res*Query(L,R,x*+);
return res;
}
}T;
LL get()
{
char ch=getchar();
while(ch!='' && ch!='')
ch=getchar();
return ch-'';
}
int main()
{
scanf("%lld%lld%lld",&n,&m,&q);
for(LL i=;i<=n;i++)
for(LL j=;j<=m;j++)
a[i][j]=get();
T.Build(,n,);
while(q--)
{
scanf("%lld%lld%lld",&op,&x,&y);
if(op==)
{
a[x][y]^=;
T.Change(,x);
}
if(op==)
{
Matrix tmp=T.Query(,n,);
printf("%lld\n",tmp.f[x][y]);
}
}
return ;
}
[2019牛客多校第二场][E. MAZE]的更多相关文章
- 2019牛客多校第二场E MAZE(线段树 + 矩阵)题解
题意: n * m的矩阵,为0表示可以走,1不可以走.规定每走一步只能向下.向左.向右走.现给定两种操作: 一.1 x y表示翻转坐标(x,y)的0.1. 二.2 x y表示从(1,x)走到(n,y) ...
- 2019牛客多校第二场 A Eddy Walker(概率推公式)
2019牛客多校第二场 A Eddy Walker(概率推公式) 传送门:https://ac.nowcoder.com/acm/contest/882/A 题意: 给你一个长度为n的环,标号从0~n ...
- 2019牛客多校第二场H-Second Large Rectangle
Second Large Rectangle 题目传送门 解题思路 先求出每个点上的高,再利用单调栈分别求出每个点左右两边第一个高小于自己的位置,从而而得出最后一个大于等于自己的位置,进而求出自己的位 ...
- [2019牛客多校第二场][G. Polygons]
题目链接:https://ac.nowcoder.com/acm/contest/882/G 题目大意:有\(n\)条直线将平面分成若干个区域,要求处理\(m\)次询问:求第\(q\)大的区域面积.保 ...
- 2019 牛客多校第二场 H Second Large Rectangle
题目链接:https://ac.nowcoder.com/acm/contest/882/H 题目大意 给定一个 n * m 的 01 矩阵,求其中第二大的子矩阵,子矩阵元素必须全部为 1.输出其大小 ...
- 2019牛客多校第二场H题(悬线法)
把以前的题补补,用悬线求面积第二大的子矩形.我们先求出最大子矩阵的面积,并记录其行三个方向上的悬线长度.然后排除这个矩形,记得还得特判少一行或者少一列的情况 #include <bits/std ...
- 2019牛客多校第二场D-Kth Minimum Clique
Kth Minimum Clique 题目传送门 解题思路 我们可以从没有点开始,把点一个一个放进去,先把放入一个点的情况都存进按照权值排序的优先队列,每次在新出队的集合里增加一个新的点,为了避免重复 ...
- 2019牛客多校第二场F-Partition problem(搜索+剪枝)
Partition problem 题目传送门 解题思路 假设当前两队的对抗值为s,如果把红队中的一个人a分配到白队,s+= a对红队中所有人的对抗值,s-= a对白队中所有人的对抗值.所以我们可以先 ...
- 2019牛客多校第二场BEddy Walker 2——BM递推
题意 从数字 $0$ 除法,每次向前走 $i$ 步,$i$ 是 $1 \sim K$ 中等概率随机的一个数,也就是说概率都是 $\frac{1}{K}$.求落在过数字 $N$ 额概率,$N=-1$ 表 ...
随机推荐
- HTML 全局属性 = HTML5 中添加的属性。
属性 描述 accesskey 规定激活元素的快捷键. class 规定元素的一个或多个类名(引用样式表中的类). contenteditable 规定元素内容是否可编辑. contextmenu 规 ...
- lua添加自定义模块的步骤
以下方法在lua 5.2.4版本下成功实现: 1. lua.c为所有函数的主程序,参考Makefile的编译链接2. lua.c中int main (int argc, char **argv) { ...
- javascript当中类型转换,typeof的用法
1)类型转换,typeof的用法 例 3.1.1 <HTML><head> <meta http-equiv="content-type" co ...
- 什么是云解析DNS?
产品概述 云解析DNS(Alibaba Cloud DNS)是一种安全.快速.稳定.可扩展的权威DNS服务,云解析DNS为企业和开发者将易于管理识别的域名转换为计算机用于互连通信的数字IP地址,从而将 ...
- centos 安装go
[root@golong-learning src]# wget https://dl.google.com/go/go1.12.7.linux-amd64.tar.gz # 下载 [root@gol ...
- PB各对象常用事件
1.window中的事件 事件名 触发的时机 01.Activate 在窗口激活之前触发 02.Clicked 当用户用 ...
- lesson10总结
package lesson10; public class Fa { String name="I am Fa"; static{ System.out.println(&qu ...
- SIP协议入门:初学者必须明白的几个重要概念
SIP协议初学者必须明白的几个重要概念 http://blog.sina.com.cn/s/blog_60e1d7bb0100f6er.html 一. SIP协议的分层结构 SIP是一个分层结构协议, ...
- 安装laravel-ide-helper
前言 使用laravel作为PHP开发框架的朋友都知道,laravel提供的门面操作都对于PHPStorm的代码提示和方法跳转都不是很友好.然而没有关系,今天介绍一个组件帮助到我们.就是!就是!就是! ...
- 小程序page中生命周期
onLoad -- 页面被加载出来 onShow -- 页面显示出来后 退出后两小时进来,只会执行这个生命周期 onRady -- (逻辑层传给渲染层后才会执行)监听页面初次渲染完成 onHide ...