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;
}
posted @ 2026-06-28 07:52  msjing  阅读(17)  评论(2)    收藏  举报