whu 643 Soul Artist(二维BIT 区间更新,单点查询) Soul Artis

【题目链接】Soul Artis

【题目类型】二维BIT

&题解:

二维区间更新和一维相比,要容斥一下,更新一块区间就是更新4个点.
还有这个我先是写了2*n2logn的算法,结果t了,想了想优化了一下,变成了n2logn,就A了,终于知道了常数的重要性 0.0

&代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define ll long long
const int maxn = 4e3 + 7;
int bit[maxn][maxn];
int Sum(int x, int y) {
	int  ans = 0;
	for (int i = x; i > 0; i -= i&-i) {
		for (int j = y; j > 0; j -= j&-j) {
			ans += bit[i][j];
		}
	}
	return ans;
}
void Add(int x, int y, int z) {
	for (int i = x; i < maxn; i += i&-i) {
		for (int j = y; j < maxn; j += j&-j) {
			bit[i][j] += z;
		}
	}
}
void Update(int x1, int y1, int x2, int y2, int z) {
	Add(x1, y1, z);
	Add(x2 + 1, y1, -z);
	Add(x1, y2 + 1, -z);
	Add(x2 + 1, y2 + 1, z);
}
int n,m,q;
int main() {
	freopen("E:1.in", "r", stdin);
	iostream::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	while(cin>>n>>m>>q) {
		memset(bit,0,sizeof(bit));
		int x,y,r;
		for(int i=0; i<q; i++) {
			cin>>x>>y>>r;
			Update(x-r-y+2000,x-r+y,x+r-y+2000,x+r+y,1);
		}
		int ma=0,te=0,num=0;
		for(int i=1; i<=n; i++) {
			for(int j=1; j<=m; j++) {
				int d=Sum(i-j+2000,i+j);
				ma=max(ma,d);
				if(ma!=te) {
					num=0;
					te=ma;
				}
				if(d==ma) {
					num++;
				}
			}
		}
		cout<<ma<<" "<<num<<endl;
	}
	return 0;
}