题目大意
给出一个(n*m)的矩阵,其中(a_{i,j}=(i-1)*m+j),现在有(k)次操作,每次将一行或一列同乘一个数(y),求最终矩阵各数之和。
(n,m leq 10^6,k leq 10^5)
分析
算是一道思博题?
可以发现各操作的顺序并不影响结果,所以可以考虑先做行操作,再做列操作。
做完行操作以后就很好求每一列之和,然后再把列操作做完。
求每列之和的方法是:先求第一列之和,然后推一推下一列之和多了多少,就能求了。
时间复杂度(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
", ans);
return 0;
}