题解 P3873【[TJOI2010]天气预报】
已知 和 ,定义 ,求 。
看着感觉很像广义斐波那契那种东西,考虑对递推式进行转化,构造矩阵出来用快速幂加速。
发现求出 需要 ,这些东西肯定要放到行向量中,那么行向量就是:
那么我们需要构造 使得 ,对着上面递推式和矩阵乘法的运算规则,可以写出下式:
也就是 。我们已知 ,所以 ,套矩阵快速幂即可。
// Problem: P3873 [TJOI2010]天气预报
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3873
// Memory Limit: 125 MB
// Time Limit: 1500 ms
//
// Powered by CP Editor (https://cpeditor.org)
//By: OIer rui_er
#include <bits/stdc++.h>
#define rep(x,y,z) for(int x=(y);x<=(z);x++)
#define per(x,y,z) for(int x=(y);x>=(z);x--)
#define debug printf("Running %s on line %d...\n",__FUNCTION__,__LINE__)
#define fileIO(s) do{freopen(s".in","r",stdin);freopen(s".out","w",stdout);}while(false)
using namespace std;
typedef long long ll;
const int N = 105, mod = 4147;
int n, m;
template<typename T> void chkmin(T& x, T y) {if(x > y) x = y;}
template<typename T> void chkmax(T& x, T y) {if(x < y) x = y;}
struct Matrix {
int n, m, a[N][N];
Matrix(int x=0, int y=0) : n(x), m(y) {
memset(a, 0, sizeof(a));
}
void e() {
assert(n == m);
rep(i, 1, n) a[i][i] = 1;
}
friend Matrix operator * (const Matrix& a, const Matrix& b) {
assert(a.m == b.n);
Matrix c(a.n, b.m);
rep(i, 1, a.n) {
rep(j, 1, b.m) {
rep(k, 1, a.m) {
c.a[i][j] += a.a[i][k] * b.a[k][j] % mod;
c.a[i][j] %= mod;
}
}
}
return c;
}
friend Matrix operator ^ (Matrix a, int k) {
assert(a.n == a.m);
Matrix ans(a.n, a.m);
ans.e();
for(;k;k>>=1,a=a*a) if(k & 1) ans = ans * a;
return ans;
}
};
int main() {
scanf("%d%d", &n, &m);
Matrix w(1, n), a(n, n);
rep(i, 1, n) scanf("%d", &w.a[1][i]);
rep(i, 1, n) scanf("%d", &a.a[i][1]);
rep(i, 2, n) a.a[i-1][i] = 1;
a = a ^ (m - n);
w = w * a;
printf("%d\n", w.a[1][1]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现