[TJOI2010] 天气预报 题解

news/2024/9/27 12:12:36

分析一下题目,大致意思就是给定一组常数 \(a_i\),然后有一个递推式 \(w_i=\sum _{j=1}^{n} w_{i-j}\times a_{j}\),让你求出 \(w_m\) 对于 \(4147\) 取模的值。

根据这个 \(1\leq m\leq 10^7\) 的恐怖范围,姑且算到了 \(O(m)\) 的时间复杂度。但是观察一下这个递推式,发现 \(O(m)\) 跑不出来。于是乎我们自然就想到了使用矩阵快速幂优化。

我们先构造出初始矩阵:

\[st= \left( \begin{matrix} w_n & w_{n-1} & \dots & w_2 & w_1 \end{matrix} \right) \]

接着我们需要将其进行转移,得到新的 \(w_{n+1}\) 的值,最后使用快速幂求出 \(w_{m}\) 的值。那么很明显,对于这个转移矩阵的第一列肯定是从 \(w_n\)\(w_{n+1}\) 的所有常数 \(a_i\),而后面的 \(n-1\) 项我们只需要直接赋值就可以了。整个式子差不多就是这个样子:

\[\left( \begin{matrix} w_{n+1} & w_{n} & \dots & w_3 & w_2 \end{matrix} \right) = \left( \begin{matrix} w_n & w_{n-1} & \dots & w_2 & w_1 \end{matrix} \right) \times \left( \begin{matrix} a_1 & 1 & 0 & \dots & 0 & 0 \\ a_2 & 0 & 1 & \dots & 0 & 0 \\ \vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\ a_{n-2} & 0 & 0 & \dots & 1 & 0 \\ a_{n-1} & 0 & 0 & \dots & 0 & 1 \\ a_n & 0 & 0 & \dots & 0 & 0 \end{matrix} \right) \]

然后我们根据快速幂,把最后的矩阵直接算出来:

\[\left( \begin{matrix} w_m & w_{m-1} & \dots & w_{m-n+2} & w_{m-n+1} \end{matrix} \right) = \left( \begin{matrix} w_n & w_{n-1} & \dots & w_2 & w_1 \end{matrix} \right) \times \left( \begin{matrix} a_1 & 1 & 0 & \dots & 0 & 0 \\ a_2 & 0 & 1 & \dots & 0 & 0 \\ \vdots & \vdots & \vdots & \ddots & \vdots & \vdots \\ a_{n-2} & 0 & 0 & \dots & 1 & 0 \\ a_{n-1} & 0 & 0 & \dots & 0 & 1 \\ a_n & 0 & 0 & \dots & 0 & 0 \end{matrix} \right) ^{m-n+1} \]

这样我们取这个矩阵的 \(w_m\) 输出来就可以了。

代码如下:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MOD=4147;
const int MAXN=105; 
int n,m;
int st[MAXN],a[MAXN];
int fr[MAXN][MAXN];
void mul(long long f[105],long long a[105][105])
{long long c[105];memset(c,0,sizeof(c));for(int j=0;j<n;j++){for(int k=0;k<n;k++)    c[j]=(c[j]+(long long)f[k]*a[k][j])%MOD;}memcpy(f,c,sizeof(c));
}
void mulself(long long a[105][105])
{long long c[105][105];memset(c,0,sizeof(c));for(int i=0;i<n;i++){for(int j=0;j<n;j++){for(int k=0;k<n;k++)    c[i][j]=(c[i][j]+(long long)a[i][k]*a[k][j])%MOD;}}memcpy(a,c,sizeof(c));
}
signed main()
{cin>>n>>m;for(int i=0;i<n;i++)	cin>>st[n-i-1];for(int i=0;i<n;i++)	cin>>a[i];for(int i=1;i<n;i++)	fr[i][i-1]=1;for(int i=0;i<n;i++)	fr[i][n-1]=a[n-i-1];int sum=m-n;while(sum){if(sum&1)	mul(st,fr);sum>>=1;mulself(fr);}cout<<st[n-1];return 0;
}

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

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

相关文章

伯俊开发回忆录---VIP充值退款增加短信验证逻辑

一、前提总部财务需要增加对VIP卡充值退款的管控,防止资金被异常盗用, 1、针对VIP充值退款获取验证码,表单增加验证码字段 2、系统随机生成6位数验证码并生成提醒信息通过公司发送平台进行发送 三、校验规则未输入验证码不允许提交 验证码校验不通过提示重新输入

我的博客生涯开始了

我的博客生涯开始了

渗透测试入门

什么是渗透测试? 定义: 渗透测试完全模拟黑客可能使用的攻击技术和漏洞发现技术,对目标系统的安全做深入的探测,发现系统最脆弱的环节,以期发现和挖掘系统中存在的漏洞,然后输出渗透测试报告,并提交给网络所有者。网络所有者根据渗透人员提供的渗透测试报告,可以清晰知…

常间的css样式问题处理

flex导致文字省略失效 单独使用文字省略,按预期工作: 给元素加上flex,文字省略失效: 解决方案:flex和文字省略不要放到一个元素上。 flex布局中,文字溢出省略不生效的问题 问题展示.container {display: flex;width: 400px;border: 1px solid #000; }.content {flex: 1; …

Spring上传文件乱码问题(问号版)

Spring上传文件乱码问题(问号版) 目录Spring上传文件乱码问题(问号版)一、问题描述:二、原因分析三、解决办法 一、问题描述: spring项目上传文件,后端接收文件并获取文件名称,名称中文变成 “?”,例如:??abc()??.xml,其中问号为中文字符 // 前端传递参数 Mult…

伯俊开发回忆录---云POS待办事项增加稽核通知功能

一、事件前景总部财务稽核通知下发流程: 1.整理EXECL通知督导, 2.督导通知对应的门店, 3.收集完反馈意见汇报给分区财务审核 4.分区财务审核之后再通知总部财务审核, 这样整个稽核流程以及周期将大大影响稽核效率,因此希望在云POS门店端直接增加待办事项减少中间沟通环节。…

我,一个小白,居然用 AI 工具修改了公司前端代码!

背景 有一天同事发现公司网站的某个页面上有三个 H1 标签,懂行的都知道,有三个 H1 标签虽然不会对网站的访问产生影响,但是对于搜索引擎来讲,就比较麻烦了,因为一般搜索引擎都是靠 H1 标签、TDK 等来对网页的内容进行抓取,然后再进行质量优劣的判断。三个 H1 标签,搜索引…

Docker打包Net8.0镜像

Docker 常用命令 Docker 是一种用于构建、打包和运行应用程序的容器化工具,以下是一些常用的 Docker 命令及其说明: 1. Docker 基础命令 docker version # 查看 Docker 的版本信息 docker info # 查看 Docker 系统信息 docker build -t <image_name> . #构建镜像 docke…