bzoj3110: [Zjoi2013]K大数查询 【cdq分治&树套树】
2015-12-23 12:40
381 查看
模板题,折腾了许久。
cqd分治整体二分,感觉像是把询问分到答案上。
View Code
cqd分治整体二分,感觉像是把询问分到答案上。
#include <bits/stdc++.h> #define rep(i, a, b) for (register int i = a; i <= b; i++) #define drep(i, a, b) for (register int i = a; i >= b; i--) #define REP(i, a, b) for (register int i = a; i < b; i++) #define pb push_back #define mp make_pair #define clr(x) memset(x, 0, sizeof(x)) #define xx first #define yy second using namespace std; typedef long long i64; typedef pair<int, int> pii; const int inf = ~0U >> 1; const i64 INF = ~0ULL >> 1; //******************************* const int maxn = 200005, maxnn = 20000005; int root[maxn << 2]; int ls[maxnn], rs[maxnn], sum[maxnn], lazy[maxnn]; int ndtot, n, N; inline void Push_up(int o) { sum[o] = sum[ls[o]] + sum[rs[o]]; } inline void Push_down(int o, int m) { if (!lazy[o]) return; if (!ls[o]) ls[o] = ++ndtot; if (!rs[o]) rs[o] = ++ndtot; lazy[ls[o]] += lazy[o], lazy[rs[o]] += lazy[o]; sum[ls[o]] += lazy[o] * (m - (m >> 1)), sum[rs[o]] += lazy[o] * (m >> 1); lazy[o] = 0; } void update(int &k, int l, int r, int ql, int qr, int v) { if (!k) k = ++ndtot; if (ql <= l && r <= qr) { sum[k] += v * (r - l + 1); lazy[k] += v; return; } int mid = l + r >> 1; Push_down(k, r - l + 1); if (ql <= mid) update(ls[k], l, mid, ql, qr, v); if (qr > mid) update(rs[k], mid + 1, r, ql, qr, v); Push_up(k); } void insrt(int o, int l, int r, int ql, int qr, int c) { while (l != r) { int mid = l + r >> 1; update(root[o], 1, n, ql, qr, 1); if (c <= mid) o <<= 1, r = mid; else o = o << 1 | 1, l = mid + 1; } update(root[o], 1, n, ql, qr, 1); } int query(int o, int l, int r, int ql, int qr) { if (!o) return 0; if (ql <= l && r <= qr) return sum[o]; Push_down(o, r - l + 1); int mid = l + r >> 1; int ret(0); if (ql <= mid) ret += query(ls[o], l, mid, ql, qr); if (qr > mid) ret += query(rs[o], mid + 1, r, ql, qr); return ret; } int solve(int o, int l, int r, int ql, int qr, int c) { while (l != r) { int mid = l + r >> 1; int t = query(root[o << 1 | 1], 1, n, ql, qr); if (t >= c) l = mid + 1, o = o << 1 |1; else r = mid, o = o << 1, c -= t; } return l; } int main() { int m; scanf("%d%d", &n, &m); N = 2 * n + 1; while (m--) { int flag, a, b, c; scanf("%d%d%d%d", &flag, &a, &b, &c); if (flag == 1) { c += n + 1; insrt(1, 1, N, a, b, c); } else printf("%d\n", solve(1, 1, N, a, b, c) - n - 1); } }
View Code
相关文章推荐
- 软件工程学习总结
- Sales Engineer
- Android 基于MVC的MVVM模式开发
- Android 基于MVC的MVVM模式开发
- 回归测试的精确化
- poj 3422 Kaka's Matrix Travels 费用流
- ip地址库选择
- 查找兄弟单词
- EEROR: "***" [***.ko] undefined! 的错误原因和解决办法
- “ 智慧的都是简单的” ——中国人的四大传统智慧
- 微软研究院Detour开发包之API拦截技术
- C++实用技巧(四)
- 大帅的有道云笔记
- C++实用技巧(三)
- 大二下学期计算机主导课程概述
- TypeError: playMovVideos() takes exactly 2 arument but 3 to given的解决方法
- Android之Http通信——3.Android HTTP请求方式:HttpURLConnection
- LeetCode --- 68. Text Justification
- 关于一个App的架构思考
- 图解堆算法、链表、栈与队列(多图预警)