题意
二维平面上给出p个点,然后q次讯问。每次讯问一个矩形内有多少个点落于里面,包涵边界。
思路
容易想到二维树状数组,但是空间炸了。可以降维处理,去掉x这一维。离散化y值,把所有点放在一起排序,每个点还有其编号、离散化后的y值、
是否是询问矩形上的点、左下角还是右上角等信息。然后按照x的大小排序,剩下的看代码。
const int MAXN =1e6 + 12;
int p, q;
struct point {
int x, y;
bool p;
bool st;
int idx, i;
int yy;
int y1, y2;
};
vector<point> vec;
bool cmp1(const point& A, const point& B) {
return A.y < B.y;
}
bool cmp2(const point& A, const point& B) {
return A.i < B.i;
}
bool cmp3(const point& A, const point& B) {
if (A.x == B.x) return A.p > B.p;
return A.x < B.x;
}
struct BIT {
int sum[MAXN];
void init() {memset(sum, 0, sizeof sum);}
void add(int pos, int val) {
while(pos < MAXN) {
sum[pos] += val;
pos += lowbit(pos);
}
}
int Getsum(int pos) {
int res = 0;
while(pos > 0) {
res += sum[pos];
pos -= lowbit(pos);
}
return res;
}
}solve;
int ans[MAXN];
int main(int argc, const char * argv[])
{
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int kase;read(kase);
while(kase--) {
read(p), read(q);
point a;
vec.clear();
Rep(i, 0, p - 1) {
scanf("%d%d", &a.x, &a.y);
a.p = true;
a.i = i;
vec.push_back(a);
}
Rep(i, 0, q - 1) {
a.i = p + 2*i;
a.p = false;
a.st = true;
a.idx = i;
scanf("%d%d", &a.x, &a.y);
a.x -= 1;//important
vec.push_back(a);
a.i = p + 2*i + 1;
a.p = false;
a.st = false;
a.idx = i;
scanf("%d%d", &a.x, &a.y);
vec.push_back(a);
}
//离散化
sort(ALL(vec), cmp1);
int num = 1;
vec[0].yy = num;
int size = vec.size();
for (int i = 1;i < size;++i) {
if (vec[i].y != vec[i-1].y) num++;
vec[i].yy = num;
}
//[1, num]
sort(ALL(vec), cmp2);
for (int i = p;i < size;i += 2) {
vec[i].y1 = vec[i].yy;
vec[i].y2 = vec[i+1].yy;
vec[i+1].y1 = vec[i].yy;
vec[i+1].y2 = vec[i+1].yy;
}
solve.init();
//x排序
sort(ALL(vec), cmp3);
for (int i = 0;i < size;++i) {
if (vec[i].p) {
solve.add(vec[i].yy, 1);
}else if (vec[i].st) {
ans[vec[i].idx] = solve.Getsum(vec[i].y2) - solve.Getsum(vec[i].y1 - 1);
}else {
ans[vec[i].idx] = solve.Getsum(vec[i].y2) - solve.Getsum(vec[i].y1 - 1) - ans[vec[i].idx];
}
}
printf("Case %d:\n", ++nCase);
for (int i = 0;i < q;++i)
printf("%d\n", ans[i]);
}
// showtime;
return 0;
}