「解题报告」AGC013E Placing Squares
想了一会然后看题解,翻到日文题解然后又关了,然后突然会了,怎么回事
第一眼生成函数!做不了。
考虑经典拆贡献方法,把平方的贡献变成从区间中选两个数的方案数。这样我们可以用一个 DP 来计数。
设
好弱智。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100005, P = 1000000007;
int n, m, a[MAXN];
struct Matrix {
int a[3][3];
Matrix() { memset(a, 0, sizeof a); }
int* operator[](int b) { return a[b]; }
const int* operator[](int b) const { return a[b]; }
Matrix operator*(Matrix b) {
Matrix c;
for (int k = 0; k < 3; k++) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
c[i][j] = (c[i][j] + 1ll * a[i][k] * b[k][j]) % P;
}
}
}
return c;
}
Matrix pow(int b) {
Matrix a = *this, ans;
ans[0][0] = ans[1][1] = ans[2][2] = 1;
while (b) {
if (b & 1) ans = ans * a;
a = a * a;
b >>= 1;
}
return ans;
}
} x, y;
int main() {
x[0][0] = 1, x[0][1] = 2, x[0][2] = 1;
x[1][0] = 0, x[1][1] = 1, x[1][2] = 1;
x[2][0] = 1, x[2][1] = 2, x[2][2] = 2;
y[0][0] = 1, y[0][1] = 2, y[0][2] = 1;
y[1][0] = 0, y[1][1] = 1, y[1][2] = 1;
y[2][0] = 0, y[2][1] = 0, y[2][2] = 1;
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++) {
scanf("%d", &a[i]);
}
a[m + 1] = n;
Matrix p = x.pow(a[1]);
for (int i = 1; i <= m; i++) {
p = p * y;
p = p * x.pow(a[i + 1] - a[i] - 1);
}
printf("%d\n", p[0][2]);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?