noip模拟赛多校第八场 T4 不要翻墙 (矩阵乘法优化DP, 动态DP)

题目描述

在这里插入图片描述

简要题意:太长了,就不总结了,自己看吧。

分析

        我们首先考虑 m = 1 m = 1 m=1 的情况:
         T > 0 T > 0 T>0 时,显然我们可以 O ( n ) O(n) O(n) 的维护一个 前缀积前缀积的逆元,然后每次询问 O ( 1 ) O(1) O(1) 得到答案就好了。时间复杂度 O ( n ) O(n) O(n)
        T = 0 T = 0 T=0 时,我们需要在 O ( n ) O(n) O(n) 的复杂度算出答案。设 d p i dp_i dpi 表示终点是 i i i 的所有路径的答案,那么转移就是 d p i = d p i − 1 × a i + a i dp_i = dp_{i - 1} \times a_i + a_i dpi=dpi1×ai+ai。然后把所有 d p i dp_i dpi 累加起来就好了。

        然后我们考虑 m = 2 m = 2 m=2 的情况:

        因为有一条限制是路径上的位置 列数要单调不降,所以我们 以列为阶段 dp,设 d p i , 0 / 1 dp_{i, 0/1} dpi,0/1 表示当起点固定,从起点到第 0 / 1 0/1 0/1 行,第 i i i 列的所有合法路径的答案。但是发现在同一列的时候可以向上走,这样的话同一列就能相互转移了。好像有后效性?

        我们考虑怎样把这个后效性去掉。我们直接列出 d p i , j dp_{i, j} dpi,j 关于 第 i − 1 i - 1 i1 列的转移:

        d p i , j = d p i − 1 , j ∗ a j , i + d p i − 1 , 1 − j ∗ a 1 − j , i ∗ a j , i dp_{i, j} = dp_{i - 1, j} * a_{j, i} + dp_{i - 1, 1 - j} * a_{1 - j, i} * a_{j, i} dpi,j=dpi1,jaj,i+dpi1,1ja1j,iaj,i

        相当于我们是以 i − 1 i - 1 i1 列是由哪个位置到达第 i i i 划分,这样能够保证不重不漏,并且没有后效性。

        有了这个式子,我们可以在 O ( T n ) O(Tn) O(Tn) 的复杂度内处理 T > 0 T > 0 T>0 的答案。在 O ( n 2 ) O(n^2) O(n2) 的复杂度内处理出 T = 0 T = 0 T=0 的答案。并且当 T ≤ 1 0 5 , n ≤ 5000 T \leq 10^5,n \leq 5000 T105n5000 时。我们可以预处理出来任意两点作为起点和终点的答案。时间复杂度是 O ( n 2 ) O(n^2) O(n2)

       这样我们就有了 45 p t s 45pts 45pts

       接下来我们思考正解:

       不难发现,转移式满足 矩阵乘法 的运算规则,并且需要加速阶段,每一阶段状态数很少,符合矩阵乘法优化DP的特点。

       设 [ d p 0 d p 1 ] \begin{bmatrix}dp_0 & dp_1 \end{bmatrix} [dp0dp1] 表示到某一列第 0 / 1 0 / 1 0/1 行的 dp 值。那么对于第 i i i 列而言,可以构建一下伴随矩阵:

[ a 0 , i a 0 , i × a 1 , i a 1 , i × a 0 , i a 1 , i ] \begin{bmatrix} a_{0,i} & a_{0, i} \times a_{1, i}\\ a_{1, i} \times a_{0, i} & a_{1, i} \end{bmatrix} [a0,ia1,i×a0,ia0,i×a1,ia1,i]

       能够发现不同列的伴随矩阵是不同的,我们使用线段树维护区间矩阵的乘积即可。

       那么 T > 0 T > 0 T>0 的情况就可以在 O ( T l o g 2 n ) O(Tlog_2n) O(Tlog2n) 的复杂度内解决。

       至于 T = 0 T = 0 T=0 的情况,我们可以在矩阵中多维护一维 S S S 表示固定一个起点时,从起点到当前列上一列的所有路径的和。伴随矩阵变成一个下列一个 3 × 3 3 \times 3 3×3 的矩阵:

[ a 0 , i a 0 , i × a 1 , i 1 a 1 , i × a 0 , i a 1 , i 1 0 0 1 ] \begin{bmatrix} a_{0,i} & a_{0, i} \times a_{1, i} & 1\\ a_{1, i} \times a_{0, i} & a_{1, i} & 1\\ 0 & 0 & 1 \end{bmatrix} a0,ia1,i×a0,i0a0,i×a1,ia1,i0111

       然后每次枚举起点算出答案并累加就好了。时间复杂度 O ( n l o g 2 n ) O(nlog_2n) O(nlog2n)

CODE:

#include<bits/stdc++.h>// 动态DP 
using namespace std;
const int N = 1e5 + 10;
typedef long long LL;
const LL mod = 1e9 + 7;
inline int read(){int x = 0, f = 1; char c = getchar();while(!isdigit(c)){if(c == '-') f = -1; c = getchar();}while(isdigit(c)){x = (x << 1) + (x << 3) + (c ^ 48); c = getchar();}return x * f;
}
struct matrix{LL mat[3][3];friend matrix operator * (matrix a, matrix b){matrix c;memset(c.mat, 0, sizeof c.mat);    	for(int i = 0; i < 3; i++)for(int j = 0; j < 3; j++)for(int k = 0; k < 3; k++)c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % mod;return c;}
};
struct SegmentTree{int l, r; matrix c;#define l(x) t[x].l#define r(x) t[x].r#define c(x) t[x].c
}t[N * 4];
int n, m, T, sx, sy, ex, ey;
LL a[2][N];
void update(int p){c(p) = c(p << 1) * c(p << 1 | 1);}
void build(int p, int l, int r){l(p) = l, r(p) = r;if(l == r){c(p).mat[0][0] = a[0][l] % mod; c(p).mat[1][0] = (a[0][l] * a[1][l]) % mod; c(p).mat[2][0] = 0;c(p).mat[0][1] = (a[0][l] * a[1][l]) % mod; c(p).mat[1][1] = a[1][l] % mod; c(p).mat[2][1] = 0;c(p).mat[0][2] = 1; c(p).mat[1][2] = 1; c(p).mat[2][2] = 1;return ;}int mid = (l + r >> 1);build(p << 1, l, mid);build(p << 1 | 1, mid + 1, r);update(p);
}
matrix ask(int p, int l, int r){if(l <= l(p) && r >= r(p)) return c(p);int mid = (l(p) + r(p) >> 1);if(r <= mid) return ask(p << 1, l, r);else if(l > mid) return ask(p << 1 | 1, l, r);else return ask(p << 1, l, r) * ask(p << 1 | 1, l, r);
}
LL query(int sx, int sy, int ex, int ey){matrix res;res.mat[0][sx] = a[sx][sy];res.mat[0][1 - sx] = (a[sx][sy] * a[1 - sx][sy]) % mod;if(sy != ey){matrix tmp = ask(1, sy + 1, ey);res = res * tmp;}return res.mat[0][ex];
}
LL solve(){LL res = 0;for(int i = 1; i <= n; i++){//枚举起点 for(int j = 0; j <= 1; j++){matrix tmp;tmp.mat[0][j] = a[j][i];tmp.mat[0][1 - j] = (a[j][i] * a[1 - j][i]) % mod;tmp.mat[0][2] = 0;if(i != n){matrix cur = ask(1, i + 1, n);tmp = tmp * cur;} res = (res + tmp.mat[0][2] + tmp.mat[0][0] + tmp.mat[0][1]) % mod;}}return res;
}
int main(){m = read(), n = read(), T = read();for(int i = 0; i < m; i++)for(int j = 1; j <= n; j++)a[i][j] = 1LL * read() % mod;build(1, 1, n);//构建矩阵if(T){while(T--){	sx = read(), sy = read(), ex = read(), ey = read();sx--, ex--;printf("%lld\n", query(sx, sy, ex, ey));}} else printf("%lld\n", solve());return 0;
}

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

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

相关文章

python基础(Python高级特性(切片、列表生成式)、字符串的正则表达式、函数、模块、Python常用内置函数、错误处理)培训讲义

文章目录 1. Python高级特性&#xff08;切片、列表生成式&#xff09;a) 切片的概念、列表/元组/字符串的切片切片的概念列表切片基本索引简单切片超出有效索引范围缺省 扩展切片step为正数step为负数 b) 列表生成式以及使用列表生成式需要注意的地方概念举例说明1. 生成一个列…

【移远QuecPython】EC800M物联网开发板的内置GNSS定位的恶性BUG(目前没有完全的解决方案)

【移远QuecPython】EC800M物联网开发板的内置GNSS定位的恶性BUG&#xff08;目前没有完全的解决方案&#xff09; GNSS配置如下&#xff1a; 【移远QuecPython】EC800M物联网开发板的内置GNSS定位获取&#xff08;北斗、GPS和GNSS&#xff09; 测试视频&#xff08;包括BUG复…

简单CMake入门

CMake可以生成不同平台下的Makefile&#xff0c;有了CMake不用再写复杂的Makefile 视频教程&#xff1a;CMake 6分钟入门&#xff0c;不用再写复杂的Makefile 先前知识 Makefile简单入门 Cmake特性 CMake是一个用于管理C/C项目的跨平台构建工具。 跨平台&#xff1a;CMake是…

【漏洞复现】Apache Log4j Server 反序列化命令执行漏洞(CVE-2017-5645)

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞扫描3、漏洞验证 1.5、深度利用1、反弹Shell 说明内容漏洞编号CVE-2017-5645漏洞名称Log4j Server …

模拟警车发声

/*----------------------------------------------- 内容&#xff1a;模拟警车发声 ------------------------------------------------*/ #include<reg52.h> //包含头文件&#xff0c;一般情况不需要改动&#xff0c;头文件包含特殊功能寄存器的定义 sbit SPKP1^2; …

判断字符串是否为json

//营业时间返回数组String businessDate merchantInfoResp.getBusinessDate();Object obj JSON.parse(businessDate);if (obj instanceof JSONArray) {merchantInfoResp.setBusinessDateDesc(JSON.parseArray(JSON.toJSONString(obj), Integer.class));} else {//营业日期判断…

【Hive】内部表(Managed Table)和外部表(External Table)相关知识点

在Hive中,有两种类型的表:外部表(External Table)和内部表(Managed Table)。它们在数据存储和管理方式上存在一些重要的区别。 本文就来对这些知识做一个总结。 1、如何在hive中创建内部表和外部表? 2、内部表和外部表的一些区别。 3、怎么查看一个表是内部表还是外部表…

Ubuntu下安装vscode,并解决终端打不开vscode的问题

Visual Studio Code安装 1&#xff0c;使用 apt 安装 Visual Studio Code 在官方的微软 Apt 源仓库中可用。按照下面的步骤进行即可&#xff1a; 以 sudo 用户身份运行下面的命令&#xff0c;更新软件包索引&#xff0c;并且安装依赖软件&#xff1a; sudo apt update sud…

09 基变换

基变换 基本概念坐标转换詹妮弗坐标系→平面直角坐标系平面直角坐标系→詹妮弗坐标系转换对比基本原则 这是关于3Blue1Brown "线性代数的本质"的学习笔记。 基本概念 对于右手平面直角坐标系&#xff0c;一般用 i ⃗ \vec{i} i 和 j ⃗ \vec{j} j ​表示其基向量。…

86.Linux系统下复制进程fork(逻辑地址和物理地址)

目录 fork复制进程 逻辑地址和物理地址 fork复制进程 fork 是一个系统调用&#xff0c;在 Linux/Unix 系统中用于创建一个新的进程&#xff0c;新进程称为子进程。子进程是父进程的副本&#xff0c;它从父进程那里继承了大部分属性和资源&#xff0c;包括代码、数据、打开的文…

VMware 虚拟机安装 CentOS 7

CentOS 7 1. 下载CentOS 7 iso镜像 Index of /centos/7.9.2009/isos/x86_64/ 2. Vmware安装CentOS 7 安装教程&#xff1a; 超详细VMware CentOS7(最小安装)安装教程_虚拟机最小化安装-CSDN博客 【精选】VMware 安装 Centos7 详细过程_vm虚拟机安装centos7_expectation Fu…

每天一道算法题:125. 验证回文串

难度 简单 题目 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后&#xff0c;短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。 字母和数字都属于字母数字字符。 给你一个字符串 s&#xff0c;如果它是 回文串 &#xff0c;返回 true_ &…

网络原理---封装和分用

文章目录 什么是封装和分用&#xff1f;封装应用层传输层网络层数据链路层物理层 分用物理层数据链路层网络层传输层应用层 什么是封装和分用&#xff1f; 我们前面讲过协议会分层&#xff0c;每一层都有各自的功能。而在数据传输的过程中&#xff0c;得按照顺序把每一层协议都…

Spring加载的过程

1. 环境准备&#xff1a; 在加载过程开始之前&#xff0c;Spring首先会进行环境准备。这包括读取配置文件、初始化配置参数等操作&#xff0c;然后创建应用上下文&#xff08;ApplicationContext&#xff09;容器。Spring支持多种配置方式&#xff0c;如XML配置、注解配置和Jav…

【ArcGIS微课1000例】0077:ArcGIS生成经纬网(shp格式)

使用ArcGIS制图的时候,可以很方便的生成经纬网、方里网及参考格网,但是在需要shp格式的经纬网,进一步在南方cass中使用经纬网的时候,就需要单独生成了。 如下图所示为全球大陆矢量数据,我们基于该数据来生成全球指定间距的经纬网数据。 在ArcGIS中,生成经纬网和方里网均…

音乐推荐与管理系统Python+Django网页界面+协同过滤推荐算法

一、介绍 音乐推荐与管理系统。本系统采用Python作为主要开发语言&#xff0c;前端使用HTML、CSS、BootStrap等技术搭建界面平台&#xff0c;后端使用Django框架处理请求&#xff0c;并基于Ajax等技术实现前端与后端的数据通信。在音乐个性推荐功能模块中采用通过Python编写协…

云原生|kubernetes |kubelet服务加入系统守护进程supervisor(centos7系统下演示通过)

前言&#xff1a; kubelet 是 Kubernetes 集群中的一个重要组件&#xff0c;运行在每个节点上&#xff0c;负责管理该节点上的容器和Pod。它与控制平面&#xff08;如 API Server 和 kube-controller-manager&#xff09;通信&#xff0c;确保节点上的容器与期望的状态保持一致…

ARMday1

1、计算机的组成 输入设备-输出设备-运算器-控制器-存储器 输入设备&#xff1a;键盘、鼠标、手柄、扫描仪 输出设备&#xff1a;显示屏、打印机、音响 存储器&#xff1a;存放数据以及指令、是实现“程序存储控制”的基础、外存、内存、cache、寄存器 控制器&#xff08;…

django安装数据库

使用pip安装django pip3 install django注意我使用的是python3所以用pip3安装&#xff0c;如需安装指定版本 django ..* 检测是否安装成功,不报错&#xff0c;则安装成功 # python3 # import django下边这是报错的 django迁移数据库 再mysql中简历数据库 CREATE DATABA…

chinese-stable-diffusion中文场景文生图prompt测评集合

腾讯混元大模型文生图操作指南.dochttps://mp.weixin.qq.com/s/u0AGtpwm_LmgnDY7OQhKGg腾讯混元大模型再进化&#xff0c;文生图能力重磅上线&#xff0c;这里是一手实测腾讯混元的文生图在人像真实感、场景真实感上有比较明显的优势&#xff0c;同时&#xff0c;在中国风景、动…