ABC260 作战总结

ABC260 作战总结

今后开始写一些模拟赛外的其他比赛的总结(也许有题解?)。

开场点到另一场\(\text{ARC}\)去了,耽误了点时间,切完前四题发现已经过了\(37\)分钟了,看来自己读题+写题的速度还有待提高。

\(\text{E}\)想了一段时间,然后发现可以差分然后尺取法,然后就切了

\(\text{F}\)的时候老师来说了两句话,稍微分了下心,再加上没有认真观察数据范围,导致思路不是很明朗,不过一会就想到了,花了\(20\text{min}\)

然而写\(\text{E,F}\)的时候都把字母打错,导致之后\(\text{18min}\)\(\text{G}\)\(\text{EX}\)了。。然后开摆,最终排名\(247\)

赛后发现\(G\)的做法没遇见过。下面简要写了\(G\)的题解。

G - Scalene Triangle Area

官方题解:https://atcoder.jp/contests/abc260/editorial/4466

我们考虑每一个石子对答案产生的贡献,大概长这样

11111110
11111000
11100000
10000000
00000000

每行都做一个差分,就变成了

+......-
+....-..
+..-....
+-......
........

考虑把这个东西处理出来,发现复杂度依然很庞大,但我们处理这个东西可以再差分

对于+

+.......
........
........
........
-.......

对于-

.......-
........
........
........
+.......

这样,每个石子就可以\(O(1)\)做了

然后做\(3\)次前缀和就行了

代码ヽ( ̄▽ ̄)ノ
#include <cstdio>
#include <iostream>
#define RE register 
#define LL long long
using namespace std;
inline void read(int &x) {
	x = 0; int f = 0; char ch = getchar();
	for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
	for(; isdigit(ch); ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);
	if(f) x = ~x + 1;
}
int n, m;
char s[2020][2020];
int vert[2020][10010], diag[2020][10010], res[2020][10010], q, x, y;
int main() {
	read(n), read(m);
	for(int i = 1; i <= n; ++i)
		scanf("%s",s[i] + 1);
	for(int i = 1; i <= n; ++i) 
		for(int j = 1; j <= n; ++j) 
			if(s[i][j] == 'O') {
				++vert[i][j], --diag[i][j + 2 * m];
				if(i + m <= n) --vert[i + m][j], ++diag[i + m][j];
			}
	for(RE int i = 1; i <= n; ++i) 
		for(RE int j = 1; j <= 10000; ++j) 
			vert[i][j] += vert[i - 1][j], diag[i][j] += diag[i - 1][j + 2];
	for(RE int i = 1; i <= n; ++i)
		for(RE int j = 1; j <= 10000; ++j)
			res[i][j] = vert[i][j] + diag[i][j];
	for(RE int i = 1; i <= n; ++i)
		for(RE int j = 1; j <= 10000; ++j)
			res[i][j] += res[i][j - 1];
	read(q);
	while(q--) {
		read(x), read(y);
		printf("%d\n",res[x][y]);
	}
}
posted @ 2022-07-18 21:11  DCH233  阅读(91)  评论(0编辑  收藏  举报