dls的資料結構-掃描線與權值線段樹
阿新 • • 發佈:2022-04-03
二維數點
1. 兩條限制,x1=<x<=x2, y1=<y<=y2, 我們可以將其轉化成單邊界的問題
2. 對於上面類似的問題都可以轉換成掃描線的形式,在該題中掃y,對x進行計數
3. 也有離線的思想
4. 事件的思想
5. vx離散化只需要離散點的x就行了,其他的不需要離散,其中lowber_bound + 1求第一個==的座標,upper_bound求最後一個<=他的座標
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N = 3e5+10; vector<array<int, 4>> events; vector<int> vx; int res[N]; LL tr[N]; int m; int lowbit(int x){ return x & (-x); } int modify(int x, LL v){ for(int i = x; i <= m; i += lowbit(i)) tr[i] += v; } LL query(int x){ LL sum = 0; for(int i = x; i; i -= lowbit(i)) sum += tr[i]; return sum; } int main(){ int n, q; scanf("%d %d", &n, &q); for(int i = 1; i <= n; i ++){ int x, y; scanf("%d %d", &x, &y); events.push_back({y, 0, x}); vx.push_back(x); } for(int i = 1; i <= q; i ++){ int x1, y1, x2, y2; scanf("%d %d %d %d", &x1, &x2, &y1, &y2); events.push_back({y2, 1, x2, i}); events.push_back({y1 - 1, 1, x1 - 1, i}); events.push_back({y1 - 1, 2, x2, i}); events.push_back({y2, 2, x1 - 1, i}); } sort(events.begin(), events.end()); sort(vx.begin(), vx.end()); vx.erase(unique(vx.begin(), vx.end()), vx.end()); m = vx.size() ; for(auto evt : events){ if(evt[1] == 0){ int x = lower_bound(vx.begin(), vx.end(), evt[2] ) - vx.begin() + 1; modify(x, 1); } else{ int x = upper_bound(vx.begin(), vx.end(), evt[2]) - vx.begin(); res[evt[3]] += (evt[1] == 1) ? query(x) : -1 * query(x); } } for(int i = 1; i <= q; i ++){ printf("%d\n", res[i]); } return 0; }