洛谷P3332 [ZJOI2013]K大數查詢(整體二分板題)
阿新 • • 發佈:2020-08-09
https://www.luogu.com.cn/problem/P3332
Code:
#include<bits/stdc++.h> #define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++) #define ff(i, x, y) for(int i = x, _b = y; i < _b; i ++) #define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --) #define ll long long #define pp printf #define hh pp("\n") using namespace std; const int N = 50005; int n, m; struct nod { int op, i; ll x, y, z; } a[N]; int ans[N]; #define V vector<int> #define pb push_back #define si size() #define i0 i + i #define i1 i + i + 1 ll t[N * 4], lz[N * 4]; int pl, pr; ll px; void jia(int i, int x, int y, ll v) { t[i] += v * (y - x + 1); lz[i] += v; } void down(int i, int x, int y) { if(lz[i]) { int m = x + y >> 1; jia(i0, x, m, lz[i]); jia(i1, m + 1, y, lz[i]); lz[i] = 0; } } void add(int i, int x, int y) { if(y < pl || x > pr) return; if(x >= pl && y <= pr) { jia(i, x, y, px); return; } int m = x + y >> 1; down(i, x, y); add(i0, x, m); add(i1, m + 1, y); t[i] = t[i0] + t[i1]; } void ft(int i, int x, int y) { if(y < pl || x > pr) return; if(x >= pl && y <= pr) { px += t[i]; return; } int m = x + y >> 1; down(i, x, y); ft(i0, x, m); ft(i1, m + 1, y); } void dg(int x, int y, V b) { if(b.empty()) return; if(x == y) { ff(i, 0, b.si) { int x = b[i]; if(a[x].op == 2) ans[a[x].i] = -y; } return; } V c, d; int m = x + y >> 1; ff(i, 0, b.si) { int x = b[i]; if(a[x].op == 1) { if(a[x].z <= m) { pl = a[x].x, pr = a[x].y, px = 1; add(1, 1, n); c.pb(x); } else { d.pb(x); } } else { pl = a[x].x, pr = a[x].y; px = 0; ft(1, 1, n); if(px < a[x].z) { a[x].z -= px; d.pb(x); } else { c.pb(x); } } } ff(i, 0, c.si) { int x = c[i]; if(a[x].op == 1) { pl = a[x].x, pr = a[x].y, px = -1; add(1, 1, n); } } dg(x, m, c); dg(m + 1, y, d); } int main() { scanf("%d %d", &n, &m); fo(i, 1, m) { scanf("%d %lld %lld %lld", &a[i].op, &a[i].x, &a[i].y, &a[i].z); if(a[i].op == 1) a[i].z = -a[i].z; a[i].i = i; } V b; fo(i, 1, m) b.pb(i); dg(-1e9 - 1, 1e9, b); fo(i, 1, m) if(a[i].op == 2) pp("%d\n", ans[i]); }