Bzoj3110: [Zjoi2013]K大数查询
2018-02-06 18:30
295 查看
题面
BzojSol
整体二分比较经典,练手题
每次的修改会影响一个区间,我用的是线段树覆盖
# include <bits/stdc++.h> # define RG register # define IL inline # define Fill(a, b) memset(a, b, sizeof(a)) using namespace std; typedef long long ll; const int _(1e5 + 5); IL ll Input(){ RG ll x = 0, z = 1; RG char c = getchar(); for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1; for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48); return x * z; } int n, m, ans[_], vis[_], tag[_ << 2]; ll sum[_ << 2], tmp[_]; struct Data{ int l, r, c, id; } q[_], q1[_], q2[_]; IL void Modify(RG int x, RG int l, RG int r, RG int L, RG int R, RG int v){ sum[x] += (R - L + 1) * v; if(L == l && R == r){ tag[x] += v; return; } RG int mid = (l + r) >> 1; if(R <= mid) Modify(x << 1, l, mid, L, R, v); else if(L > mid) Modify(x << 1 | 1, mid + 1, r, L, R, v); else Modify(x << 1, l, mid, L, mid, v), Modify(x << 1 | 1, mid + 1, r, mid + 1, R, v); } IL ll Query(RG int x, RG int l, RG int r, RG int L, RG int R, RG ll ad){ if(L == l && R == r) return sum[x] + ad * (r - l + 1); RG int mid = (l + r) >> 1; ad += tag[x]; if(R <= mid) return Query(x << 1, l, mid, L, R, ad); if(L > mid) return Query(x << 1 | 1, mid + 1, r, L, R, ad); return Query(x << 1, l, mid, L, mid, ad) + Query(x << 1 | 1, mid + 1, r, mid + 1, R, ad); } IL void Solve(RG int l, RG int r, RG int L, RG int R){ if(L > R) return; if(l == r){ for(RG int i = L; i <= R; ++i) ans[q[i].id] = l; return; } RG int mid = (l + r) >> 1, t1 = 0, t2 = 0; for(RG int i = L; i <= R; ++i) if(vis[q[i].id]) tmp[q[i].id] = Query(1, 1, n, q[i].l, q[i].r, 0); else if(q[i].c > mid) Modify(1, 1, n, q[i].l, q[i].r, 1); for(RG int i = L; i <= R; ++i) if(vis[q[i].id]){ if(tmp[q[i].id] >= q[i].c) q2[++t2] = q[i]; else q[i].c -= tmp[q[i].id], q1[++t1] = q[i]; } else{ if(q[i].c <= mid) q1[++t1] = q[i]; else q2[++t2] = q[i]; } for(RG int i = L; i <= R; ++i) if(!vis[q[i].id] && q[i].c > mid) Modify(1, 1, n, q[i].l, q[i].r, -1); for(RG int i = L, j = 1; j <= t1; ++i, ++j) q[i] = q1[j]; for(RG int i = L + t1, j = 1; j <= t2; ++i, ++j) q[i] = q2[j]; Solve(l, mid, L, L + t1 - 1); Solve(mid + 1, r, L + t1, R); } int main(RG int argc, RG char* argv[]){ n = Input(); m = Input(); RG int mn = 2147483647, mx = -mn; for(RG int i = 1; i <= m; ++i){ RG int op = Input(); q[i].l = Input(), q[i].r = Input(), q[i].c = Input(), q[i].id = i; if(op == 1) mx = max(mx, q[i].c), mn = min(mn, q[i].c); vis[i] = op == 2; } Solve(mn, mx, 1, m); for(RG int i = 1; i <= m; ++i) if(vis[i]) printf("%d\n", ans[i]); return 0; }
相关文章推荐
- [BZOJ3110][Zjoi2013]-K大数查询-树套树
- BZOJ 3110: [Zjoi2013]K大数查询( 树状数组套主席树 )
- HDU 5412 CRB and Queries && BZOJ 3110: [Zjoi2013]K大数查询 (整体二分+树状数组/线段树)
- 【bzoj 3110】[Zjoi2013]K大数查询
- bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树
- 【ZJOI2013】【BZOJ3110】K大数查询
- 【整体二分】[ZJOI 2013] bzoj3110 K大数查询
- 【bzoj3110】 Zjoi2013—K大数查询
- BZOJ 3110: [Zjoi2013]K大数查询 [树套树]
- BZOJ 3110([Zjoi2013]K大数查询-区间第k大[段修改,在线]-树状数组套函数式线段树)
- BZOJ 3110: [Zjoi2013]K大数查询
- [BZOJ3110][ZJOI2013]K大数查询(线段树套线段树)
- 【BZOJ3110】【ZJOI2013】K大数查询
- BZOJ 3110 (zjoi 2013)k大数查询(树套树)
- bzoj 3110 [Zjoi2013]K大数查询【树套树||整体二分】
- Bzoj3110 [Zjoi2013]K大数查询 [整体二分]
- 【bzoj3110】[Zjoi2013]K大数查询 权值线段树套区间线段树
- [BZOJ3110][Zjoi2013]K大数查询
- 【bzoj3110】[Zjoi2013]K大数查询 权值线段树套区间线段树
- 【BZOJ 3110】【ZJOI 2013】K大数查询