BZOJ1935: [Shoi2007]Tree 园丁的烦恼(树状数组 二维数点)
题意
Sol
二维数点板子题
首先把询问拆成四个矩形
然后离散化+树状数组统计就可以了
// luogu-judger-enable-o2
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 4e6 + 10;
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;
}
int N, M, x[MAXN], y[MAXN], a[MAXN], b[MAXN], c[MAXN], d[MAXN], dx[MAXN], dy[MAXN], nx, ny, cnt, ans[MAXN];
struct Node {
int y, opt, id;
bool operator < (const Node &rhs) const {
return y < rhs.y;
}
};
vector<Node> q[MAXN];
vector<int> v[MAXN];
void des(int *d, int &num) {
sort(d + 1, d + num + 1);
num = unique(d + 1, d + num + 1) - d - 1;
}
int find(int *d, int num, int val) {
return lower_bound(d + 1, d + num + 1, val) - d;
}
struct BIT {
#define lb(x) (x & (-x))
int T[MAXN];
void Add(int x, int v) {
for(; x <= ny; x += lb(x))
T[x] += v;
}
int Query(int x) {
int ans = 0;
while(x) ans += T[x], x -= lb(x);
return ans;
}
#undef lb
}T;
void solve() {
for(int i = 0; i <= nx; i++) {
for(int j = 0; j < v[i].size(); j++)
T.Add(v[i][j], 1);
for(int j = 0; j < q[i].size(); j++) {
ans[q[i][j].id] += q[i][j].opt * T.Query(q[i][j].y);
}
}
}
signed main() {
N = read(); M = read();
for(int i = 1; i <= N; i++) x[i] = dx[++nx] = read(), y[i] = dy[++ny] = read();
for(int i = 1; i <= M; i++) {
a[i] = dx[++nx] = read(), b[i] = dy[++ny] = read(), c[i] = dx[++nx] = read(), d[i] = dy[++ny] = read();
//dx[++nx] = a[i] - 1; dy[++ny] = b[i] - 1; dx[++nx] = c[i] - 1; dy[++ny] = d[i] - 1;
}
des(dx, nx);
des(dy, ny);
for(int i = 1; i <= N; i++) {
x[i] = find(dx, nx, x[i]);
y[i] = find(dy, ny, y[i]);
v[x[i]].push_back(y[i]);
}
for(int i = 1; i <= M; i++) {
a[i] = find(dx, nx, a[i]); b[i] = find(dy, ny, b[i]); c[i] = find(dx, nx, c[i]); d[i] = find(dy, ny, d[i]);
q[c[i]].push_back((Node) {d[i], 1, i});
q[a[i] - 1].push_back((Node) {d[i], -1, i});
q[c[i]].push_back((Node) {b[i] - 1, -1, i});
q[a[i] - 1].push_back((Node) {b[i] - 1, 1, i});
}
solve();
for(int i = 1; i <= M; i++) printf("%d\n", ans[i]);
return 0;
}
/*
6 2
2 2
3 2
3 3
3 4
4 3
5 4
3 1 5 3
1 1 3 5
3
*/
作者:自为风月马前卒
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。