# UVALive 7141 BombX（离散化+线段树）（2014 Asia Shanghai Regional Contest）

In an infinite chess board, some pawns are placed on some cells.
You have a rectangular bomb that is W width and H height.
The bomb’s orientation is fixed, you can’t rotate it. The bomb
can only be placed on an entirely unoccupied area. The bomb
explodes both horizontally and vertically, killing all pawns that
are in the cross shape (see picture on the right).
Your mission is to choose the placement of the bomb, and
maximize the number of bombed pawns.
The picture corresponds to the first test case in the sample.
Input
The first line of the input gives the number of test cases, T. T
test cases follow. Each test case starts with a line containing N,
W, H, indicating number of pawns, width of the bomb, height of
the bomb, respectively.
N lines follow. Each line contains 2 integers: x, y, indicating there is a pawn on cell (x, y). No two
pawns are in the same cell.
Output
For each test case, output one line containing ‘Case #x: y’, where x is the test case number (stating
from 1) and y is the maximum number of bombed pawns.

PS：范围写的是w, h≥0，于是我加了一个assert，目前数据是没有w, h=0的情况的。如果rejudge RE了我就知道怎么回事啦！

  1 #include <cstdio>
2 #include <algorithm>
3 #include <iostream>
4 #include <cstring>
5 #include <vector>
6 #include <tuple>
7 #include <cassert>
8 using namespace std;
9 typedef long long LL;
10
11 const int MAXN = 100010;
12 const int MAXL = 200010;
13 const int MAXT = 400010;
14
15 struct Node {
16     int x, y;
18         scanf("%d%d", &x, &y);
19     }
20 } p[MAXN];
21
22 int val[MAXL];
23
24 vector<int> ytmp;
25
26 int T, n, w, h;
27
28 void inithash() {
29     ytmp.clear();
30     for(int i = 0; i < n; ++i) {
31         ytmp.push_back(p[i].y - h + 1);
32         ytmp.push_back(p[i].y + 1);
33     }
34     sort(ytmp.begin(), ytmp.end());
35     ytmp.erase(unique(ytmp.begin(), ytmp.end()), ytmp.end());
36 }
37
38 int yhash(int y) {
39     return lower_bound(ytmp.begin(), ytmp.end(), y) - ytmp.begin();
40 }
41
42 void initval() {
43     memset(val, 0, ytmp.size() * sizeof(int));
44     for(int i = 0; i < n; ++i) {
45         val[yhash(p[i].y - h + 1)]++;
46         val[yhash(p[i].y + 1)]--;
47     }
48     partial_sum(val, val + ytmp.size(), val);
49 }
50
51 int root(int l, int r) {
52     return (l + r) | (l != r);
53 }
54 #define mid ((l + r) >> 1)
55 #define rt root(l, r)
56 #define ll root(l, mid)
57 #define rr root(mid + 1, r)
58 int ban[MAXT], maxt[MAXT];
59
60 void update(int l, int r) {
61     if(!ban[rt]) maxt[rt] = (l == r ? val[l] : max(maxt[ll], maxt[rr]));
62     else maxt[rt] = 0;
63 }
64
65 void build(int l, int r) {
66     if(l == r) {
67         maxt[rt] = val[l];
68     } else {
69         build(l, mid);
70         build(mid + 1, r);
71         update(l, r);
72     }
73 }
74
75 void modify_ban(int l, int r, int a, int b, int val) {
76     if(a <= l && r <= b) {
77         ban[rt] += val;
78     } else {
79         if(a <= mid) modify_ban(l, mid, a, b, val);
80         if(mid < b) modify_ban(mid + 1, r, a, b, val);
81     }
82     update(l, r);
83 }
84
85 int query() {
86     return maxt[root(0, ytmp.size() - 1)];
87 }
88
89 vector<int> allx;
90 vector<tuple<int, int, int> > xtmp;
91 #define gpos(t) get<0>(t)
92 #define gval(t) get<1>(t)
93 #define gy(t) get<2>(t)
94
95 int solve() {
96     xtmp.clear();
97     for(int i = 0; i < n; ++i) {
98         xtmp.push_back(make_tuple(p[i].x - w + 1, 1, p[i].y));
99         xtmp.push_back(make_tuple(p[i].x + 1, -1, p[i].y));
100     }
101     sort(xtmp.begin(), xtmp.end());
102
103     allx.clear();
104     for(int i = 0; i < n; ++i) {
105         allx.push_back(p[i].x - w + 1);
106         allx.push_back(p[i].x + 1);
107     }
108     sort(allx.begin(), allx.end());
109     allx.erase(unique(allx.begin(), allx.end()), allx.end());
110
111     int res = query(), cnt = 0;
112     size_t i = 0;
113     for(int x : allx) {
114         while(i < xtmp.size() && gpos(xtmp[i]) <= x) {
115             auto t = xtmp[i++];
116             modify_ban(0, ytmp.size() - 1, yhash(gy(t) - h + 1), yhash(gy(t) + 1) - 1, gval(t));
117             cnt += gval(t);
118         }
119         res = max(res, query() + cnt);
120     }
121     return res;
122 }
123
124 int main() {
125     scanf("%d", &T);
126     for(int t = 1; t <= T; ++t) {
127         scanf("%d%d%d", &n, &w, &h);
128         assert(w > 0 && h > 0);
129         for(int i = 0; i < n; ++i)
136 }