[传送门]
把一个询问拆成4个询问,即二维前缀和的形式,又变成了二维矩阵求和/RMQ的问题,有了[51nod 1463找朋友]的启发,直接按$x$排序,再对$y$查询即可,区间前缀和可以用树状数组来实现,常数小而且好写。
#include <bits/stdc++.h> using namespace std; const int N = 2e6 + 7; const int M = 5e6 + 7; int n, m, Y[M], toty, ans[N]; namespace IO { const int MAXSIZE = 1 << 24; char buf[MAXSIZE], *p1, *p2; #define gc() \ (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, MAXSIZE, stdin), p1 == p2) ? EOF : *p1++) inline int rd() { int x = 0, f = 1; char c = gc(); while (!isdigit(c)) { if (c == ‘-‘) f = -1; c = gc(); } while (isdigit(c)) x = x * 10 + (c ^ 48), c = gc(); return x * f; } char pbuf[1 << 20], *pp = pbuf; inline void push(const char &c) { if (pp - pbuf == 1 << 20) fwrite(pbuf, 1, 1 << 20, stdout), pp = pbuf; *pp++ = c; } inline void write(int x) { static int sta[35]; int top = 0; do { sta[top++] = x % 10, x /= 10; } while (x); while (top) push(sta[--top] + ‘0‘); } } using namespace IO; struct BIT { int tree[N]; inline int lowbit(int x) { return x & -x; } void add(int x) { for (int i = x; i <= n; i += lowbit(i)) tree[i]++; } int query(int x) { int ans = 0; for (int i = x; i; i -= lowbit(i)) ans += tree[i]; return ans; } } bit; struct IN { int x, y; inline bool operator < (const IN &rhs) const { return x < rhs.x || (x == rhs.x && y < rhs.y); } } in[N]; vector<int> G[N]; struct QUERY { int x, y, id; bool flag; inline bool operator < (const QUERY &rhs) const { return x < rhs.x || (x == rhs.x && y < rhs.y); } } query[M]; int main() { freopen("in.txt", "r", stdin); n = rd(), m = rd(); int q = 0; for (int i = 1; i <= n; i++) { in[i].x = rd(); in[i].y = rd(); Y[++toty] = in[i].y; } for (int i = 1; i <= m; i++) { int a = rd(), b = rd(), c = rd(), d = rd(); Y[++toty] = b - 1, Y[++toty] = d; query[++q] = (QUERY){a - 1, b - 1, i, 1}; query[++q] = (QUERY){a - 1, d, i, 0}; query[++q] = (QUERY){c, b - 1, i, 0}; query[++q] = (QUERY){c, d, i, 1}; } sort(Y + 1, Y + toty + 1); toty = unique(Y + 1, Y + 1 + toty) - Y - 1; for (int i = 1; i <= n; i++) in[i].y = lower_bound(Y + 1, Y + toty + 1, in[i].y) - Y; for (int i = 1; i <= q; i++) query[i].y = lower_bound(Y + 1, Y + toty + 1, query[i].y) - Y; sort(in + 1, in + 1 + n); sort(query + 1, query + 1 + q); int now = 1; for (int i = 1; i <= q; i++) { while (now <= n && in[now].x <= query[i].x) { bit.add(in[now].y); now++; } if (query[i].flag == 1) { ans[query[i].id] += bit.query(query[i].y); } else { ans[query[i].id] -= bit.query(query[i].y); } } for (int i = 1; i <= m; i++) printf("%d\n", ans[i]); return 0; }
BZOJ1935. [Shoi2007]Tree 园丁的烦恼
原文:https://www.cnblogs.com/Mrzdtz220/p/11673079.html