AtCoder Beginner Contest 464 E - Fill-Rect Query 题解
msjing想到正解了但是觉得10min码不出来所以放弃了
solve
- 考虑到是覆盖,可以感性理解一下,认为每次操作都是盖地毯,那么每次操作都有优先级,越往后优先级越高
- 因此我们考虑倒着做,
msjing想到了但是没写,每次先从\(r[k]\)向上推,只要\(g[i][c[k]]\)不为A就停掉整个i的循环,之后在break下从\(c[k]\)开始同样找,如果是0就改颜色,否则break - 这么做是否能保证正确性呢,考虑到所有修都是从\((1,1)\)开始,所以不需要考虑其他问题,直接从下和右卡就行了
- 复杂度其实我最开始认为很劣,但是再一想:
每个点至多被改一次
——zhangjiaheng
- 所以最多就是\(O(nm)\)
- 综合为\(O(Qnm)\)
- 最后就是数组怎么开了,开常规数组直接让你飞起来,所以我们开vector:
vector<vector<int> > g(n+5,vector<int> (m+5,0)); wang79现教的
code
#include<bits/stdc++.h>
using namespace std;
constexpr int maxn=1e6+10;
long long read()
{
long long x=0,f=1;
char ch=getchar();
while (ch<'0' || ch>'9')
{
if (ch == '-') f=-1;
ch=getchar();
}
while (ch>='0' && ch<='9')
{
x=(x<<1)+(x<<3)+ch-'0';
ch=getchar();
}
return x*f;
}
int n,m,Q;
char x[maxn];
int r[maxn],c[maxn];
int main()
{
n=read(),m=read(),Q=read();
vector<vector<int> > g(n+5,vector<int> (m+5,0));
for (int i=1;i<=Q;i++) r[i]=read(),c[i]=read(),x[i]=getchar();
for (int k=Q;k>=1;k--)
{
for (int i=r[k];i>=1;i--)
{
if (g[i][c[k]]!=0) break;
for (int j=c[k];j>=1;j--)
{
if (g[i][j]!=0) break;
g[i][j]=x[k];
}
}
}
for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (!g[i][j]) g[i][j]='A';
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++) printf("%c",g[i][j]);
printf("\n");
}
return 0;
}

浙公网安备 33010602011771号