链接
http://poj.org/problem?id=2029
题意
给你一个 W × H W\times H W×H的公园,告诉你这个公园里栽有 n n n棵柿子树,并且告诉你这 n n n个柿子树的坐标,现在问你大小为 s × t s\times t s×t的土地上最多有多少棵柿子树;
分析
二维线段树,把一维的树状数组,及插入函数 i n s e r t insert insert和求和函数 s u m sum sum均变成二维即可,每告诉一个柿子树坐标 ( x , y ) (x, y) (x,y),就在该位置插入一个1, s u m ( x , y ) sum(x, y) sum(x,y),即是求横坐标小于等于 x x x,纵坐标小于等于 y y y的那块区域的柿子树个数,所以我们枚举 s × t s\times t s×t的一个顶点,求出这块区域的柿子树个数,然后更新最大值即可,如果我们枚举给定区域最右下角的点,个数为 s u m ( x , y ) + s u m ( x − s , y − t ) − s u m ( x , y − t ) − s u m ( x − s , y ) sum(x,\ y) + sum(x - s,\ y - t) - sum(x,\ y - t) - sum(x - s,\ y) sum(x, y)+sum(x−s, y−t)−sum(x, y−t)−sum(x−s, y);最后还需要注意,对于0的 l o w b i t lowbit lowbit运算是无意义的;
代码
#include <functional>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <set>
#include <map>
#define INF 0x7f7f7f7f
#define MAXN 1000005
#define N 200005
#define P 2
#define MOD 99991
typedef long long ll;
namespace fastIO {
//#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1<<22, stdin), p1 == p2) ? EOF : *p1++)
//char buf[(1 << 22)], *p1 = buf, *p2 = buf;
inline int read() {
char c = getchar(); int x = 0, f = 1;
while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
}
using namespace fastIO;
using namespace std;
int n, w, h, c[560][560];
void insert(int x, int y) {
for (int i = x; i <= w; i += i & -i)
for (int j = y; j <= h; j += j & -j)
c[i][j] += 1;
}
int sum(int x, int y) {
if (x <= 0 || y <= 0)return 0;
int res = 0;
for (int i = x; i > 0; i -= i & -i)
for (int j = y; j > 0; j -= j & -j)
res += c[i][j];
return res;
}
int main() {
while (cin >> n, n) {
cin >> w >> h;
int x, y;
memset(c, 0, sizeof(c));
for (int i = 1; i <= n; i++) {
cin >> x >> y;
insert(x, y);
}
cin >> x >> y;
int maxm = 0;
for (int i = x; i <= w; i++)
for (int j = y; j <= h; j++) {
int cnt = sum(i, j) + sum(i - x, j - y) - sum(i, j - y) - sum(i - x, j);
maxm = max(maxm, cnt);
}
cout << maxm << endl;
}
}