题目链接: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]的更多相关文章

  1. 2019牛客多校第二场E MAZE(线段树 + 矩阵)题解

    题意: n * m的矩阵,为0表示可以走,1不可以走.规定每走一步只能向下.向左.向右走.现给定两种操作: 一.1 x y表示翻转坐标(x,y)的0.1. 二.2 x y表示从(1,x)走到(n,y) ...

  2. 2019牛客多校第二场 A Eddy Walker(概率推公式)

    2019牛客多校第二场 A Eddy Walker(概率推公式) 传送门:https://ac.nowcoder.com/acm/contest/882/A 题意: 给你一个长度为n的环,标号从0~n ...

  3. 2019牛客多校第二场H-Second Large Rectangle

    Second Large Rectangle 题目传送门 解题思路 先求出每个点上的高,再利用单调栈分别求出每个点左右两边第一个高小于自己的位置,从而而得出最后一个大于等于自己的位置,进而求出自己的位 ...

  4. [2019牛客多校第二场][G. Polygons]

    题目链接:https://ac.nowcoder.com/acm/contest/882/G 题目大意:有\(n\)条直线将平面分成若干个区域,要求处理\(m\)次询问:求第\(q\)大的区域面积.保 ...

  5. 2019 牛客多校第二场 H Second Large Rectangle

    题目链接:https://ac.nowcoder.com/acm/contest/882/H 题目大意 给定一个 n * m 的 01 矩阵,求其中第二大的子矩阵,子矩阵元素必须全部为 1.输出其大小 ...

  6. 2019牛客多校第二场H题(悬线法)

    把以前的题补补,用悬线求面积第二大的子矩形.我们先求出最大子矩阵的面积,并记录其行三个方向上的悬线长度.然后排除这个矩形,记得还得特判少一行或者少一列的情况 #include <bits/std ...

  7. 2019牛客多校第二场D-Kth Minimum Clique

    Kth Minimum Clique 题目传送门 解题思路 我们可以从没有点开始,把点一个一个放进去,先把放入一个点的情况都存进按照权值排序的优先队列,每次在新出队的集合里增加一个新的点,为了避免重复 ...

  8. 2019牛客多校第二场F-Partition problem(搜索+剪枝)

    Partition problem 题目传送门 解题思路 假设当前两队的对抗值为s,如果把红队中的一个人a分配到白队,s+= a对红队中所有人的对抗值,s-= a对白队中所有人的对抗值.所以我们可以先 ...

  9. 2019牛客多校第二场BEddy Walker 2——BM递推

    题意 从数字 $0$ 除法,每次向前走 $i$ 步,$i$ 是 $1 \sim K$ 中等概率随机的一个数,也就是说概率都是 $\frac{1}{K}$.求落在过数字 $N$ 额概率,$N=-1$ 表 ...

随机推荐

  1. There are no packages available

    { "bootstrapped": true, "channels": [ "https://raw.githubusercontent.com/Ja ...

  2. spring cloud微服务docker启动

    1. 背景 将系统拆分成微服务,一个系统可能拆分成十几个服务,服务太多会影响发布和管理,所以容器话之后易于管理和版本发布,鉴于此将spring cloud微服无docker容器化. 2.依赖环境 Ce ...

  3. Oracle定时调用存储过程

    #1Demo: 1.创建表 create table job_table(run_time date); 2.创建存储过程 create or replace procedure job_proc i ...

  4. 关于JS原型以及原型链、instanceof的一些理解

    一.JS原型 首先要区分两个概念 1.构造函数 2.实例:由构造函数通过new方式创建出来的就是实例 <script> function Foo() { } var f = new Foo ...

  5. 【01字典树】hdu-5536 Chip Factory

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5536 [题意] 求一个式子,给出一组数,其中拿出ai,aj,ak三个数,使得Max{ (ai+aj ...

  6. 【搜索】n的约数

    题目链接:传送门 [题解]: 考察dfs和质因数分解,首先开一个prime数组. 参数解释: 1.当前值的大小.[利用题目的n来控制范围] 2.控制下界,每次都是以某一个质数开始搜索, pos 3.控 ...

  7. 【转载】STM32 IAP 在线升级详解

      (扩展-IAP主要用于产品出厂后应用程序的更新作用,考虑到出厂时要先烧写IAP  再烧写APP应用程序要烧写2次增加工人劳动力基础上写了“STM32 IAP+APP ==>双剑合一”链接稍后 ...

  8. visual studio 用 vs code 的 hot key

    记得 2 年多前开始用 vs code, 一开始非常不适应它的 hot key 一心想把 vs code 的 hot key 全改成 visual studio 的,但一直没有找到比较方便的办法 (总 ...

  9. MySQL 官方样板数据库sakila

    Sakila示例数据库最初由MySQL AB文档团队的前成员Mike Hillyer开发,旨在提供可用于书籍,教程,文章,样本等示例的标准模式. Sakila示例数据库还用于突出MySQL的最新功能, ...

  10. antd做form表单的组件共用,利用mapPropsToFields填写默认值

    做单页应用,不管是用Vue还是React,或者其他,有一个重要的原则,就是:组件重用. 既然组件可以重用,那么当添加一个信息,和修改该信息的布局必然是一致的,这时候,最好的方法自然是利用同一个组件,在 ...