正题


题目大意

一个n∗mn*mn∗m的迷宫,不能往左走,有墙,每次修改一个点或询问两个点之间的最短距离。


解题思路

考虑到nnn的值很小,所以我们可以用矩阵转移,然后要求支持修改和查询所以我们考虑ddpddpddp。
我们可以用矩阵代替线段树的权值,然后区间查询即可。

时间复杂度O((m+qlog⁡m)n3)O((m+q\log m)n^3)O((m+qlogm)n3)


codecodecode

#pragma GCC optimize(2)
%:pragma GCC optimize(3)
%:pragma GCC optimize("Ofast")
%:pragma GCC optimize("inline")
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int Size=5,N=201000;
struct Matrix{int a[Size][Size];
}c,ans;
struct Tree_node{int l,r;Matrix w;
}t[N*4];
int n,m,q,v[Size][N],flag;
Matrix operator*(const Matrix &a,const Matrix &b)
{memset(c.a,0x3f,sizeof(c.a));for(int i=0;i<n;i++)for(int j=0;j<n;j++)for(int k=0;k<n;k++)c.a[i][j]=min(c.a[i][j],a.a[i][k]+b.a[k][j]);return c;
}
struct Seq_Tree{void Build(int x,int l,int r){memset(t[x].w.a,0x3f,sizeof(t[x].w.a));t[x].l=l;t[x].r=r;if(l==r){for(int i=0;i<n;i++){bool up=1,down=1;if(!v[i][l]){continue;}for(int j=0;j<n;j++){if(i+j>=n||!v[i+j][l]) up=0;if(i-j<0||!v[i-j][l]) down=0;if(!up&&!down) break;if(up) t[x].w.a[i+j][i]=j+1;if(down) t[x].w.a[i-j][i]=j+1; }}return;}int mid=(l+r)/2;Build(x*2,l,mid);Build(x*2+1,mid+1,r);t[x].w=t[x*2].w*t[x*2+1].w;}void Ask(int x,int l,int r){if(t[x].l==l&&t[x].r==r){if(!flag) ans=t[x].w,flag=1;else ans=ans*t[x].w;return;}int mid=(t[x].l+t[x].r)/2;if(r<=mid) Ask(x*2,l,r);else if (l>mid) Ask(x*2+1,l,r);else Ask(x*2,l,mid),Ask(x*2+1,mid+1,r);}void Change(int x,int z){if(t[x].l==t[x].r){memset(t[x].w.a,0x3f,sizeof(t[x].w.a));int l=t[x].l;for(int i=0;i<n;i++){bool up=1,down=1;if(!v[i][l]){memset(t[x].w.a[i],0x3f,sizeof(t[x].w.a[i]));continue;}for(int j=0;j<n;j++){if(i+j>=n||!v[i+j][l]) up=0;if(i-j<0||!v[i-j][l]) down=0;if(!up&&!down) break;if(up) t[x].w.a[i+j][i]=j+1;if(down) t[x].w.a[i-j][i]=j+1; }}return;}int mid=(t[x].l+t[x].r)/2;if(z<=mid) Change(x*2,z);else Change(x*2+1,z);t[x].w=t[x*2].w*t[x*2+1].w; }
}T;
int main()
{freopen("maze.in","r",stdin);freopen("maze.out","w",stdout);scanf("%d%d%d",&n,&m,&q);for(int i=0;i<n;i++)for(int j=1;j<=m;j++)scanf("%d",&v[i][j]);T.Build(1,1,m);while(q--){int op,a,b,x,y;scanf("%d%d%d",&op,&a,&b);if(op==1){a--;v[a][b]=!v[a][b];T.Change(1,b);}if(op==2){scanf("%d%d",&x,&y);if(y<b){printf("-1\n");continue;}if(b==y){if(x>a) swap(x,a);x--;a--;flag=0;for(int i=x;i<=a;i++)if(!v[i][b]){flag=1;break;}if(flag) printf("-1\n");else printf("%d\n",a-x);continue;}flag=0;T.Ask(1,b,y-1);x--;a--;bool up=1,down=1;int mins=2147483647;for(int i=0;i<n;i++){if(x+i>=n||!v[x+i][y]) up=0;if(x-i<0||!v[x-i][y]) down=0;if(!up&&!down) break;if(up) mins=min(mins,ans.a[a][x+i]+i);if(down) mins=min(mins,ans.a[a][x-i]+i); } if(mins>n*m){printf("-1\n");continue;}printf("%d\n",mins);}}
}

jzoj6293-迷宫【ddp,线段树,矩阵乘法】相关推荐

  1. LOJ2980 THUSC2017大魔法师(线段树+矩阵乘法)

    线段树每个节点维护(A,B,C,len)向量,操作即是将其乘上一个矩阵. #include<iostream> #include<cstdio> #include<cma ...

  2. 牛客 - 求函数(线段树+区间合并/线段树+矩阵维护)

    题目链接:点击查看 题目大意:现在有 n 个函数,每个函数都是诸如 f( x ) = k * x + b 的形式,只是每个函数的 k 和 b 都是相互独立的,现在给出两个操作: 1 pos k b:将 ...

  3. 线段树 + 矩阵 --- ZOJ 3772 Calculate the Function

    Calculate the Function Problem's Link:   http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCod ...

  4. luogu P5142 区间方差(线段树、乘法逆元)

    luogu P5142 区间方差 本题要求维护模区间方差,很明显是一道数据结构题. 我们化简方差公式: 而平均数等于 可以发现,我们只需要维护序列的区间和和区间平方和,就可以维护平均数和方差. 区间和 ...

  5. New Year and Old Subsequence CodeForces - 750E(线段树+矩阵dp)2019南昌icpc网络赛Hello 2019

    A string t is called nice if a string "2017" occurs in t as a subsequence but a string &qu ...

  6. 2018.10.09 ZYH的斐波那契数列(线段树+矩阵快速幂)

    描述 ZYH最近研究数列研究得入迷啦! 现在有一个斐波拉契数列(f[1]=f[2]=1,对于n>2有f[n]=f[n-1]+f[n-2]), 但是斐波拉契数列太简单啦,于是ZYH把它改成了斐波拉 ...

  7. 河南省多校联盟二-F 线段树+矩阵

    ---恢复内容开始--- 1284: SP教数学 时间限制: 2 秒  内存限制: 128 MB 提交: 24  解决: 4 题目描述 输入 输出 对于每组数据的2操作,输出一行对1e9 + 7取模的 ...

  8. NOIP模拟题 [线段树][矩阵快速幂]

    有一定难度,要深入挖掘问题特性. T1: 题意: 给定一个序列,每次操作把操作位置及其后面比它小的数按顺序排列(整体上仍在原来的位置),求每次操作后的逆序对数. 分析: 每个数对逆序对数都有一个贡献( ...

  9. 算法竞赛从入门到进阶pdf_【算法趣谈】线段树 从入门到进阶

        前言:这是一篇笔者两年前所写的博客.如今,在线段树在脑海中即将遗忘之际,这两年前留下的文章,终于将其再次唤醒.这篇文章对于线段树的理解虽谈不上绝对深刻,但是也能详细且简明地解释其流程.因而也收 ...

最新文章

  1. 用Flutter + Dart快速构建一款绝美移动App
  2. 分享一款超棒的jQuery旋钮插件 - jQuery knob
  3. AXI总线基本知识:(基于uart_lite IP核)
  4. x86 X64指令集之间的关系
  5. linux对2k屏幕,(转)Linux中的screen命令使用
  6. 使用 SAP UI5 系统测试工具 UIVeri5 的一个具体例子
  7. VS2015编译boost 1.62.0
  8. 全国计算机等级考试题库二级C操作题100套(第81套)
  9. 小扎不哭!FB又陷数据泄露风波,9000万用户受影响
  10. jquery ajax调用服务器端指定的函数的三种方式
  11. mysql query generator_mybatis generator生成连接mysql与sqlserver的区别
  12. 求助动态贝叶斯网络参数学习函数的使用方法
  13. Windows PC HYSPLIT Install
  14. [Github实战]双重认证2FA 如何 设置/更改[手把手][2022]
  15. 学计算机的制作水印,如何设置属于自己的水印,电脑上制作属于自己的文字水印...
  16. 伪标签(Pseudo-Labelling)
  17. android高德地图获取海拔_高德地图如何测海拔
  18. 【计算机网络】Stanford CS144 学习笔记
  19. neo4j :rel_Neo4j:足球转移图表
  20. 文献(8): 单细胞和空间分析揭示FAP+成纤维细胞和SPP1+巨噬细胞在结直肠癌中的相互作用

热门文章

  1. php程序员跟java一样吗,【后端开辟】php程序员能够转java吗?
  2. 刷新mac地址命令_配置好Cisco交换机需要熟悉IOS命令及相关的知识
  3. qdialog 只有点击才能获得焦点_4 个突破点,让你的 Banner 点击率提升10倍
  4. python os rename用法_Python os.rename() 方法
  5. mysql查询重复的名字_Mysql中like用法:查询名字中含有风字的学生信息
  6. Linux vi 双屏显示,manjaro AwesomeWM 上使用双显示器
  7. python 防止转义_python字符串前加r、f、u、l 的区别
  8. vs 2019 aspx灰色_蛇纹当道,豹纹在侧:穿成动物园是2019时尚大势?
  9. [JS-DOM]DOM概述
  10. [JavaWeb-JavaScript]JavaScript_Array数组对象