博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
洛谷 P3332 BZOJ 3110 [ZJOI2013]K大数查询
阅读量:4983 次
发布时间:2019-06-12

本文共 2676 字,大约阅读时间需要 8 分钟。

题目链接

题解

整体二分

Code

#include
#define LL long long#define RG registerusing namespace std;inline int gi() { RG int x = 0; RG char c = getchar(); bool f = 0; while (c != '-' && (c < '0' || c > '9')) c = getchar(); if (c == '-') c = getchar(), f = 1; while (c >= '0' && c <= '9') x = x*10+c-'0', c = getchar(); return f ? -x : x;}const int N = 50010;int n, m;#define ls (rt<<1)#define rs (rt<<1|1)LL t[N<<2], z[N<<2];inline void pushdown(int rt, int l, int r) { if (z[rt]) { int mid = (l + r) >> 1; t[ls] += (mid-l+1)*z[rt]; t[rs] += (r-mid)*z[rt]; z[ls] += z[rt]; z[rs] += z[rt]; z[rt] = 0; } return;}inline void update(int rt, int l, int r, int L, int R, int k) { if (L <= l && r <= R) { z[rt] += k; t[rt] += k*(r-l+1); return ; } int mid = (l + r) >> 1; pushdown(rt, l, r); if (L <= mid) update(ls, l, mid, L, R, k); if (R > mid) update(rs, mid+1, r, L, R, k); t[rt] = t[ls]+t[rs]; return ;}inline LL query(int rt, int l, int r, int L, int R) { if (L <= l && r <= R) return t[rt]; int mid = (l + r) >> 1; LL s = 0; pushdown(rt, l, r); if (L <= mid) s = query(ls, l, mid, L, R); if (R > mid) s += query(rs, mid+1, r, L, R); t[rt] = t[ls]+t[rs]; return s;}struct Question { int op, a, b, id; LL c;}q[N], lq[N], rq[N];LL ans[N];void div(int l, int r, int st, int ed) { if (st > ed) return ; if (l == r) { for (int i = st; i <= ed; i++) if (q[i].op == 2) ans[q[i].id] = l; return ; } int mid = (l + r) >> 1, lt = 0, rt = 0; for (int i = st; i <= ed; i++) { if (q[i].op == 1) { if (q[i].c <= mid) lq[++lt] = q[i]; else update(1, 1, n, q[i].a, q[i].b, 1), rq[++rt] = q[i]; } else { LL s = query(1, 1, n, q[i].a, q[i].b); if (s >= q[i].c) rq[++rt] = q[i]; else q[i].c -= s, lq[++lt] = q[i]; } } for (int i = st; i <= ed; i++) if (q[i].op == 1 && q[i].c > mid) update(1, 1, n, q[i].a, q[i].b, -1); for (int i = 1; i <= lt; i++) q[st+i-1] = lq[i]; for (int i = 1; i <= rt; i++) q[st+lt+i-1] = rq[i]; div(l, mid, st, st+lt-1); div(mid+1, r, st+lt, ed); return ;}int main() { n = gi(); m = gi(); int k = 0; for (int i = 1; i <= m; i++) { q[i].op = gi(), q[i].a = gi(), q[i].b = gi(); scanf("%lld", &q[i].c); q[i].id = (q[i].op == 2) ? ++k : 0; } div(-n, n, 1, m); for (int i = 1; i <= k; i++) printf("%lld\n", ans[i]); return 0;}

转载于:https://www.cnblogs.com/zzy2005/p/10153733.html

你可能感兴趣的文章
python openpyxl内存不主动释放 ——关闭Excel工作簿后内存依旧(MemoryError)
查看>>
snprintf 返回值陷阱 重新封装
查看>>
asp.net GridView多行表头的实现,合并表头
查看>>
C#套打
查看>>
codeforce 932E Team Work(第二类斯特林数)
查看>>
PolyCluster: Minimum Fragment Disagreement Clustering for Polyploid Phasing 多聚类:用于多倍体的最小碎片不一致聚类...
查看>>
【每日进步】July 2012
查看>>
Cookie登录保存
查看>>
327 作业
查看>>
sql 取汉字首字母
查看>>
python3 字符串属性(四)
查看>>
javascript 封装ajax(多版本)
查看>>
bzoj4034: [HAOI2015]树上操作(树剖)
查看>>
android-Activity
查看>>
${sessionScope.user}的使用方法
查看>>
IOS断点下载
查看>>
Steal 偷天换日 题解(From luoguBlog)
查看>>
Hadoop HDFS学习总结
查看>>
C#wxpay和alipay
查看>>
Combination Sum
查看>>