模板题,折腾了许久。
cqd分治整体二分,感觉像是把询问分到答案上。
1 #include <bits/stdc++.h> 2 #define rep(i, a, b) for (int i = a; i <= b; i++) 3 #define drep(i, a, b) for (int i = a; i >= b; i--) 4 #define REP(i, a, b) for (int i = a; i < b; i++) 5 #define pb push_back 6 #define mp make_pair 7 #define clr(x) memset(x, 0, sizeof(x)) 8 #define xx first 9 #define yy second 10 using namespace std; 11 typedef long long i64; 12 typedef pair<int, int> pii; 13 const int inf = ~0U >> 1; 14 const i64 INF = ~0ULL >> 1; 15 template <typename T> void Max(T &a, T &b) { if (a < b) a = b; } 16 template <typename T> void Min(T &a, T &b) { if (a > b) a = b; } 17 //****************************************** 18 19 const int maxn = 50005; 20 21 struct Seg_Tree { 22 int sum[maxn << 3], lazy[maxn << 3]; 23 void Push_down(int o, int m) { 24 if (!lazy[o]) return; 25 lazy[o << 1] += lazy[o], lazy[o << 1 | 1] += lazy[o]; 26 sum[o << 1] += lazy[o] * (m - (m >> 1)), sum[o << 1 | 1] += lazy[o] * (m >> 1); 27 lazy[o] = 0; 28 } 29 void Push_up(int o) { sum[o] = sum[o << 1] + sum[o << 1 | 1]; } 30 void update(int o, int l, int r, int ql, int qr, int v) { 31 if (ql <= l && r <= qr) { 32 lazy[o] += v; 33 sum[o] += v * (r - l + 1); 34 return; 35 } 36 Push_down(o, r - l + 1); 37 int mid = l + r >> 1; 38 if (ql <= mid) update(o << 1, l, mid, ql, qr, v); 39 if (qr > mid) update(o << 1 | 1, mid + 1, r, ql, qr, v); 40 Push_up(o); 41 } 42 int query(int o, int l, int r, int ql, int qr) { 43 if (ql <= l && r <= qr) return sum[o]; 44 Push_down(o, r - l + 1); 45 int mid = l + r >> 1; 46 int ret(0); 47 if (ql <= mid) ret += query(o << 1, l, mid, ql, qr); 48 if (qr > mid) ret += query(o << 1 | 1, mid + 1, r, ql, qr); 49 return ret; 50 } 51 void CLR() { clr(sum), clr(lazy); } 52 } T; 53 54 struct Complex { 55 int flag, x, y, c, id; 56 inline bool operator < (const Complex &A) const { 57 return id < A.id; 58 } 59 } src[maxn]; 60 61 int N, ans[maxn], v[maxn]; 62 void cdq(int ansl, int ansr, int l, int r) { 63 if (ansl == ansr) { 64 rep(i, l, r) if (src[i].flag == 2) ans[src[i].id] = ansl; 65 return; 66 } 67 if (l > r) return; 68 sort(src + l, src + r + 1); 69 int m = ansl + ansr + 1 >> 1; 70 int j = l; 71 rep(i, l, r) { 72 if (src[i].flag == 1) { 73 if (src[i].c >= m) T.update(1, 1, N, src[i].x, src[i].y, 1), v[i] = 1; 74 else v[i] = 0; 75 } 76 else { 77 int t = T.query(1, 1, N, src[i].x, src[i].y); 78 if (t >= src[i].c) v[i] = 1; 79 else src[i].c -= t, v[i] = 0; 80 } 81 j += !v[i]; 82 } 83 rep(i, l, r) 84 if (src[i].flag == 1) 85 if (src[i].c >= m) T.update(1, 1, N, src[i].x, src[i].y, -1); 86 int t = j - 1; 87 if (j != l) 88 rep(i, l, t) { 89 while (j < r && v[j]) ++j; 90 if (v[i]) swap(src[i], src[j]), swap(v[i], v[j]), ++j; 91 } 92 cdq(ansl, m - 1, l, t); 93 cdq(m, ansr, t + 1, r); 94 } 95 96 int read() { 97 int l = 1, s = 0; char ch = getchar(); 98 while (ch < '0' || ch > '9') { if (ch == '-') l = -1; ch = getchar(); } 99 while (ch >= '0' && ch <= '9') { s = (s << 1) + (s << 3) + ch - '0'; ch = getchar(); } 100 return s * l; 101 } 102 int main() { 103 int n, m; scanf("%d%d", &n, &m); 104 rep(i, 1, m) scanf("%d%d%d%d", &src[i].flag, &src[i].x, &src[i].y, &src[i].c), src[i].id = i; 105 N = n; 106 cdq(-n, n, 1, m); 107 sort(src + 1, src + 1 + m); 108 rep(i, 1, m) if (src[i].flag == 2) printf("%d\n", ans[i]); 109 return 0; 110 }