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

news2025/1/19 11:23:16

题目描述

在这里插入图片描述

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

分析

        我们首先考虑 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.coloradmin.cn/o/1177699.html

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

相关文章

基于鹈鹕算法的无人机航迹规划-附代码

基于鹈鹕算法的无人机航迹规划 文章目录 基于鹈鹕算法的无人机航迹规划1.鹈鹕搜索算法2.无人机飞行环境建模3.无人机航迹规划建模4.实验结果4.1地图创建4.2 航迹规划 5.参考文献6.Matlab代码 摘要&#xff1a;本文主要介绍利用鹈鹕算法来优化无人机航迹规划。 1.鹈鹕搜索算法 …

x86汇编代码学习-计算机工作原理1

文章目录 前言1.CPU架构2.8086寄存器3. 指令流水线4.内存模型5.总线6.硬盘7 计算机启动过程BIOS8.BootLoader9.地址映射10.为什么boot loader要放在0x7c00这个位置&#xff1f;11 显卡是如何显示的12.汇编指令1.环境搭建 12 程序13 x86 汇编指令介绍 前言 x86汇编 详解x86汇编…

虚拟机联网 | 虚拟机连接Xshell

目录 一&#xff0c;打开网络虚拟编辑器二&#xff0c;打开网络设置三&#xff0c;最终设置四&#xff0c;测试有没有连上网五&#xff0c;测试连接工具Xshell 一&#xff0c;打开网络虚拟编辑器 1. 点击"编辑"&#xff0c;打开"虚拟网络编译器" 2. 选择更…

SHEIN要求卖家完成德国EPR合规,逾期将强制下架——站斧浏览器

EPR是卖家在欧盟自由销售的通行证之一&#xff0c;如果没有&#xff0c;是不允许在欧盟国家销售产品的。 近期根据SHEIN官方邮件通知&#xff0c;卖家需要在收到邮件后5天内完成申报&#xff0c;逾期申报产品将会在德国站点下架。 因此&#xff0c;建议卖家尽快通过合规的服务…

第八章《搞懂算法:逻辑回归是怎么回事》笔记

8.1 如何理解逻辑回归 逻辑回归根据给定的自变量数据集来估计事件的发生概率&#xff0c;由于结果是一个概率&#xff0c;因此因变量的范围在 0 和 1 之间。 逻辑回归的与线性回归一样&#xff0c;也是以线性函数为基础的&#xff1b;而与线性回归不同的是&#xff0c;逻辑回…

智能安全配电装置在银行配电系统中的应用

【摘要】银行是国家重点安全保护部分&#xff0c;关系到社会资金的稳定&#xff0c;也是消防重点单位&#xff0c;消防安全保障工作是银行工作的重要方面。智能安全配电装置应用在银行配电系统中&#xff0c;可以提升银行智能化管控水平和有效防范电气火灾的发生。 【关键词】…

【QT】QT自定义C++类

在使用Qt的ui设计时&#xff0c;Qt为我们提供了标准的类&#xff0c;但是在很多复杂工程中&#xff0c;标准的类并不能满足所有的需求&#xff0c;这时就需要我们自定义C类。 下面以自定义的QPushButton作一个很简单的例子。 先新建默认Qt Widgets Application项目 一、自定义…

从传统货架到智能货架电子标签PTL仓储亮灯系统的革新

在现代物流仓储行业中&#xff0c;仓库的管理和物料的寻找一直是一个难题。仓库内物料数量种类繁多&#xff0c;寻找物料耗时长、困难大&#xff0c;盘点更是耗费人力多、成本高、速度慢。此外&#xff0c;货物存储位置不清晰&#xff0c;经常性找不到物料。多发、少发、错料现…

首个流体力学大模型背后,是昇腾的大模型“造林”逻辑

作者 | 曾响铃 文 | 响铃说 一个飞机模型在试验风洞里&#xff0c;空气从它的机翼与机身流过&#xff0c;形成一层又一层稳定的气流&#xff0c;当风速加快&#xff0c;空气的流线开始波浪式摆动&#xff0c;最终随着速度增大而相互混合、形成不再能分辨的湍流&#xff0c;看…

大模型的实践应用5-百川大模型(Baichuan-13B)的模型搭建与模型代码详细介绍,以及快速使用方法

大家好,我是微学AI,今天给大家介绍一下大模型的实践应用5-百川大模型(Baichuan-13B)的模型搭建与模型代码详细介绍,以及快速使用方法。 Baichuan-13B 是由百川智能继 Baichuan-7B 之后开发的包含 130 亿参数的开源可商用的大规模语言模型,在权威的中文和英文 benchmark 上均…

【寒武纪(3)】媒体处理系统的系统控制、视频输入和后处理子系统

系统控制 文章目录 系统控制1、配置视频缓存池Video Pool2、配置硬件IP为在线工作&#xff08;不通过DDR数据交互&#xff09;/ 离线工作&#xff08;写入DDR&#xff09;模式3、硬IP可以使用 非Video Block &#xff08;VB&#xff09;内存4、配置是否启动内存传递的压缩 视频…

Elasticsearch:搜索架构

Elasticsearch 全文检索的复杂性 为了理解为什么全文搜索是一个很难解决的问题&#xff0c;让我们想一个例子。 假设你正在托管一个博客发布网站&#xff0c;其中包含数亿甚至数十亿的博客文章&#xff0c;每个博客文章包含数百个单词&#xff0c;类似于 CSDN。 执行全文搜索…

c++-红黑树

文章目录 前言一、红黑树1、红黑树的概念2、红黑树的性质3、红黑树节点的定义4、红黑树结点插入4.1 情况1&#xff1a;cur为红&#xff0c;p为红&#xff0c;g为黑&#xff0c;存在且为红4.2 情况2&#xff1a;cur为红&#xff0c;p为红&#xff0c;g为黑&#xff0c;u不存在/u…

Unity之NetCode多人网络游戏联机对战教程(6)--NetworkTransform组件

文章目录 前言NetworkTransform是什么玩家移动脚本NetworkTransform字段讲解Synchronizing ("Syncing")ThresholdsLocal spaceInterpolationSlerp PositionUse Quaternion SynchronizationUse Quaternion CompressionUse Half Float PrecisionAuthority modesServer …

银河E8,吉利版Model 3:5米大车身、45寸大屏、首批8295座舱芯

作者 | Amy 编辑 | 德新 吉利银河E8在曝光后多次引爆热搜&#xff0c;李书福更是赞誉有加&#xff0c;称其为「买了就直接享受」。这款备受瞩目的车型于 10月30日晚首次亮相。 虽然新车外观在今年上海车展上早已曝光&#xff0c;但这次的发布会却带来了不少惊喜。新车架构以及…

pytorch安装1

用豆瓣源安装pytorch1.5.1&#xff08;速度很快&#xff09;-CSDN博客 详情请参考这位神仙的博客 我真的哭死&#xff0c;原来torch都安装好了&#xff0c;好不容易全部加载好了&#xff0c;但是&#xff0c;gpu配不上去&#xff0c;后来发现还是版本的问题版本不匹配具体版本…

Element对象_属性

Element对象对应网页的HTML元素。每一个HTML元素&#xff0c;在DOM树上都会转化成一个Element节点对象&#xff08;以下简称元素节点&#xff09; 1、Element.id Element.id属性返回指定元素的id属性&#xff0c;该属性可读写 2、Element.className className属性用来读写当前…

k8s 1.28安装

容器运行时&#xff0c;containerd 按照官方的指导&#xff0c;需要安装runc和cni插件&#xff0c;提示的安装方式&#xff0c;有三种&#xff1a; 二进制安装包源码apt-get 或 dnf安装 我们这里选用第三种&#xff0c;找到docker官方提供的安装方式 ubuntu-containerd # A…

rhcsa-文件内容显示

浏览普通文件内容 浏览文件的命令 命令常用选项说明cat -n 对输出内容中的所有行标注行号 -b 对输出内容中的非空行标注行号 查看文件的内容head-num 指定需要显示文件num行的内容默认查看文前十行的内容tail -num 指定需要显示文件num行的内容 -f 使tail不停的去读取显示文…

PHP保存时自动删除末尾的空格,phpstorm自动删除空白字符串

最近有个活儿&#xff0c;修改一个财务软件。 修改后给客户验收的过程中&#xff0c;客户反应有一个txt表格导出功能不能用了。之前是好的。 这次是新增&#xff0c;老的这个功能碰都没碰过&#xff0c;怎么能有问题呢&#xff1f;我心里OS 下班后我立马用系统导出TXT&#…