1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
| #include <iostream> #include <tuple> #include <queue> #define maxn 2010 #define maxm 100010 #define lowbit(i) ((i) & (-i)) using namespace std;
const int r = 2000; const int c = 2000;
int n, q;
struct HeapMax { priority_queue<int> add, del;
inline void push(int x) { add.push(x); }
inline void erase(int x) { del.push(x); }
inline int top() { while (!del.empty() && del.top() == add.top()) del.pop(), add.pop(); return add.top(); }
inline void pop() { while (!del.empty() && del.top() == add.top()) del.pop(), add.pop(); add.pop(); }
inline bool empty() { return add.size() - del.size() == 0; } };
struct HeapMin { priority_queue<int, vector<int>, greater<int>> add, del;
inline void push(int x) { add.push(x); }
inline void erase(int x) { del.push(x); }
inline int top() { while (!del.empty() && del.top() == add.top()) del.pop(), add.pop(); return add.top(); }
inline void pop() { while (!del.empty() && del.top() == add.top()) del.pop(), add.pop(); add.pop(); }
inline bool empty() { return add.size() - del.size() == 0; } };
#define lc i << 1 #define rc i << 1 | 1 struct Seg { HeapMin s; HeapMax t; } T[maxn * 4]; void build(int i, int l, int r) { T[i].s.push(n + 1), T[i].t.push(0); if (l == r) return ; int m = l + r >> 1; build(lc, l, m); build(rc, m + 1, r); }
void update(int i, int l, int r, int L, int R, int v, int opt) { if (l > R || r < L) return ; if (L <= l && r <= R) { if (opt > 0) T[i].s.push(v), T[i].t.push(v); else T[i].s.erase(v), T[i].t.erase(v); return ; } int m = l + r >> 1; update(lc, l, m, L, R, v, opt); update(rc, m + 1, r, L, R, v, opt); }
int mn[maxn][maxn], mx[maxn][maxn]; void query(int i, int l, int r, int s, int t, int k) { if (l == r) return mn[k][l] = min(T[i].s.top(), s), mx[k][l] = max(T[i].t.top(), t), void(); int m = l + r >> 1; s = min(s, T[i].s.top()); t = max(t, T[i].t.top()); query(lc, l, m, s, t, k); query(rc, m + 1, r, s, t, k); }
vector<tuple<int, int, int>> A[maxn], B[maxn];
int ans[maxm]; vector<int> C[maxm]; vector<pair<int, int>> D[maxm];
int Bit[maxm]; void add(int i, int v) { while (i <= n) Bit[i] += v, i += lowbit(i); }
int get_sum(int i) { int s = 0; while (i) s += Bit[i], i -= lowbit(i); return s; }
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
cin >> n >> q; for (int i = 1; i <= n; ++i) { int x1, x2, y1, y2; cin >> x1 >> y1 >> x2 >> y2; ++x1; ++y1; A[x1].emplace_back(y1, y2, i); B[x2].emplace_back(y1, y2, i); } for (int i = 1; i <= r; ++i) for (int j = 1; j <= c; ++j) mn[i][j] = n + 1, mx[i][j] = 0; build(1, 1, c); for (int i = 1; i <= r; ++i) { for (auto t : A[i]) { int l, r, v; tie(l, r, v) = t; update(1, 1, c, l, r, v, 1); } query(1, 1, c, n + 1, 0, i); for (auto t : B[i]) { int l, r, v; tie(l, r, v) = t; update(1, 1, c, l, r, v, -1); } } for (int i = 1; i <= q; ++i) { int x, y; cin >> x >> y; D[y].emplace_back(x, i); } for (int i = 1; i <= r; ++i) for (int j = 1; j <= c; ++j) if (mn[i][j] < n + 1 && mx[i][j] > 0) C[mx[i][j]].push_back(mn[i][j]); int sum = 0; for (int i = 1; i <= n; ++i) { for (auto t : C[i]) ++sum, add(t, 1); for (auto t : D[i]) ans[t.second] = sum - get_sum(t.first - 1); } for (int i = 1; i <= q; ++i) cout << sum - ans[i] << "\n"; return 0; }
|