【JZOJ6277】【NOIP提高组A】矩阵游戏
题目大意
给出一个n∗m的矩阵,其中ai,j=(i−1)∗m+j,现在有k次操作,每次将一行或一列同乘一个数y,求最终矩阵各数之和。
n,m≤106,k≤105
分析
算是一道思博题?
可以发现各操作的顺序并不影响结果,所以可以考虑先做行操作,再做列操作。
做完行操作以后就很好求每一列之和,然后再把列操作做完。
求每列之和的方法是:先求第一列之和,然后推一推下一列之和多了多少,就能求了。
时间复杂度O(n+m+k)。
Code
#include <cstdio>
#include <cstring>
#define F(i, l, r) for (int i = l; i <= r; ++i)
typedef long long ll;
const int N = 1000007;
const ll P = 1e9 + 7;
int n, m, k, x[N], y[N];
short opt[N];
ll ans, s, s1, fir, las, sum[N], mtp[N], p[N];
char c;
int main()
{
freopen("game.in", "r", stdin);
freopen("game.out", "w", stdout);
scanf("%d%d%d", &n, &m, &k);
F(i, 1, k)
{
scanf(" %c%d%d", &c, &x[i], &y[i]);
opt[i] = (c == 'R' ? 1 : 0);
}
F(i, 1, n) mtp[i] = 1;
F(i, 1, k) if (opt[i]) mtp[x[i]] = mtp[x[i]] * y[i] % P;
F(i, 1, n) s = (s + (mtp[i] - 1 + P) % P * (1ll * (i - 1) * m % P + 1) % P) % P, s1 = (s1 + (mtp[i] - 1 + P) % P) % P;
F(i, 1, m)
{
fir = i, las = (i + 1ll * (n - 1) * m % P) % P;
sum[i] = 1ll * (fir + las) * n % P * 500000004ll % P;
sum[i] = (sum[i] + s) % P, s = (s + s1) % P;
p[i] = 1;
}
F(i, 1, k) if (!opt[i]) p[x[i]] = p[x[i]] * y[i] % P;
F(i, 1, m) ans = (ans + p[i] * sum[i] % P) % P;
printf("%lld\n", ans);
return 0;
}
作者:zjlcnblogs
出处:https://www.cnblogs.com/zjlcnblogs/p/11305778.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步