题意:
给你\(n * m\)的网格,\(k\)种颜色,\(p\)次操作。每次操作,给你一个坐标\((x_i, y_i)\) ,你可以选择一种颜色将这个点的所在行和所在列涂色,并且每个格子上新的涂色会覆盖原来的涂色,问你最后网格的涂色情况有多少种?
思路:
分析答案的构成:
我们要预处理出所有网格最后一次涂色的时间,然后看有多少种不同的涂色时间,答案就是 \(k^{cnt}\)。
如何维护每个格子最后涂色的时间?
一共有\(p\)次操作,我们可以倒着分析,可以不考虑覆盖问题,在所有格子没有被涂满时,每一次的操作就一定会给新的格子上色,当所有格子被涂满时,那么格子的颜色就不会发生改变,直接跳出循环。
代码:
void solve()
{
memset(stc, 0, sizeof stc);
memset(stl, 0, sizeof stl);
scanf("%d %d %d %d",&n, &m, &k, &q);
for(int i = 1; i <= q; i ++ )
scanf("%d %d",&color[i].fi, &color[i].se);
int sum = 0;
int cntl = 0, cntr = 0;
for(int i = q; i >= 1; i -- ){
int x = color[i].fi, y = color[i].se;
if(cntl == n || cntr == m) break;
bool flag = false;
if(!stl[x]){
cntl ++;
stl[x] = true;
flag = true;
}
if(!stc[y]){
cntr ++;
stc[y] = true;
flag = true;
}
if(flag) sum ++;
}
LL ans = 1;
for(int i = 1; i <= sum; i ++ ) ans = (ans * k) % mod;
printf("%lld\n",ans);
}