题解 P4521 【[COCI2017-2018 Contest4] Automobil 】
Description
给你一个大小为
Solution
首先注意到
然后可以注意到,只需要求出最后矩阵中数字的和,所以这个操作的顺序是无所谓的,可以把操作排序,先处理行操作,然后处理出每一列的数字和,记作
然后考虑如何处理行操作。可以把每一行乘的数算出来,记作
原矩阵的一行中,后一个数等于前一个数
这之后你就可以对着一维问题乱搞了。
时间复杂度
Code
#include <cstdio>
#include <algorithm>
const int maxn = 1000010;
const int maxk = 1010;
const int mod = 1000000007;
int inline pls(int a, int b) { int m = a + b; return m < mod ? m : m - mod; }
int inline dec(int a, int b) { int m = a - b; return m < 0 ? m + mod : m; }
int inline mul(int a, int b) { return 1ll * a * b % mod; }
struct qry {
int o, x, y;
bool operator < (const qry &rhs) const {
return o < rhs.o;
}
} a[maxk];
int val[maxn], f[maxn];
int main() {
static int n, m, k, x, y, s, ans; char opt[2];
scanf("%d%d%d", &n, &m, &k);
for (int i = 1; i <= k; ++i) {
scanf("%s%d%d", opt, &x, &y);
a[i] = (qry){*opt == 'S', x, y};
}
std::sort(a + 1, a + k + 1);
for (int i = 1; i <= n; ++i) val[i] = 1;
for (int i = 1; i <= k; ++i) {
if (a[i].o) break;
val[a[i].x] = mul(val[a[i].x], a[i].y);
}
for (int i = 1; i <= n; ++i) s = pls(s, val[i]);
for (int i = 1; i <= n; ++i) f[1] = pls(f[1], mul(pls(mul(m, i - 1), 1), val[i]));
for (int i = 2; i <= m; ++i) f[i] = pls(f[i - 1], s);
for (int i = 1; i <= k; ++i) {
if (!a[i].o) continue;
f[a[i].x] = mul(f[a[i].x], a[i].y);
}
for (int i = 1; i <= m; ++i) ans = pls(ans, f[i]);
printf("%d\n", ans);
return 0;
}