Get Many Persimmon Trees 【POJ - 2029】【二維線段樹】
阿新 • • 發佈:2018-11-30
題目連結【簡單題】
一道簡單的二維線段樹,查詢的是一個規定長寬的長方形內的最多點數,因為W、H都比較的小,所以不妨可以直接上暴力二維線段樹查詢即可。
#include <iostream> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <algorithm> #include <limits> #include <vector> #include <stack> #include <queue> #include <set> #include <map> #define lowbit(x) ( x&(-x) ) #define efs 1e-6 #define pi 3.141592653589793 #define e 2.718281828459045 using namespace std; typedef unsigned long long ull; typedef long long ll; const int maxN = 105; int a[maxN][maxN], W, H, N, S, T, tree[maxN<<2][maxN<<2]; void build_In(int rt, int xo, int pos, int l, int r, bool flag) { if(l == r) { if(flag) tree[xo][rt] = a[pos][l]; else tree[xo][rt] = tree[xo<<1][rt] + tree[xo<<1|1][rt]; return; } int mid = (l + r)>>1; build_In(rt<<1, xo, pos, l, mid, flag); build_In(rt<<1|1, xo, pos, mid+1, r, flag); tree[xo][rt] = tree[xo][rt<<1] + tree[xo][rt<<1|1]; } void build_Out(int rt, int l, int r) { if(l == r) { build_In(1, rt, l, 1, H, true); return; } int mid = (l + r)>>1; build_Out(rt<<1, l, mid); build_Out(rt<<1|1, mid+1, r); build_In(1, rt, 0, 1, H, false); } int query_In(int rt, int xo, int l, int r, int ql, int qr) { if(ql<=l && qr>=r) return tree[xo][rt]; int mid = (l + r)>>1; if(ql>mid) return query_In(rt<<1|1, xo, mid+1, r, ql, qr); else if(qr<=mid) return query_In(rt<<1, xo, l, mid, ql, qr); else { int ans = query_In(rt<<1|1, xo, mid+1, r, ql, qr); ans += query_In(rt<<1, xo, l, mid, ql, qr); return ans; } } int query_Out(int rt, int l, int r, int qlx, int qly, int qrx, int qry) { if(qlx<=l && qrx>=r) return query_In(1, rt, 1, H, qly, qry); int mid = (l + r)>>1; if(qlx>mid) return query_Out(rt<<1|1, mid+1, r, qlx, qly, qrx, qry); else if(qrx<=mid) return query_Out(rt<<1, l, mid, qlx, qly, qrx, qry); else { int ans = query_Out(rt<<1|1, mid+1, r, qlx, qly, qrx, qry); ans += query_Out(rt<<1, l, mid, qlx, qly, qrx, qry); return ans; } } int main() { while(scanf("%d", &N) && N) { scanf("%d%d", &W, &H); memset(a, 0, sizeof(a)); for(int i=1; i<=N; i++) { int e1, e2; scanf("%d%d", &e1, &e2); a[e1][e2]++; } build_Out(1, 1, W); scanf("%d%d", &S, &T); int ans = 0; for(int i=1; i+S-1<=W; i++) { for(int j=1; j+T-1<=H; j++) { ans = max(ans, query_Out(1, 1, W, i, j, i+S-1, j+T-1)); } } printf("%d\n", ans); } return 0; }