1 条题解
-
0
#include <algorithm> #include <cstdio> #include <cmath> #define MaxN 105000 using namespace std; int BS, a[MaxN], b[MaxN], p[MaxN], tag[100]; int p1[1400], p2[1400]; inline bool cmp(int A, int B) { return a[A] < a[B]; } void build(int t, int l, int r) { int tl = t * BS, tr = tl + BS, n1 = 0, n2 = 0; for (int i = tl; i < tr; i++) if (l <= p[i] && p[i] <= r) p1[++n1] = p[i]; else p2[++n2] = p[i]; merge(p1 + 1, p1 + n1 + 1, p2 + 1, p2 + n2 + 1, p + tl, cmp); for (int i = tl; i < tr; i++) b[i] = a[p[i]]; } void add(int l, int r, int x) { int bl = l / BS, br = r / BS; if (bl == br) { for (int i = l; i <= r; i++) a[i] += x; build(bl, l, r); } else { for (int i = l; i < bl * BS + BS; i++) a[i] += x; for (int i = br * BS; i <= r; i++) a[i] += x; build(bl, l, bl * BS + BS - 1); build(br, br * BS, r); for (int i = bl + 1; i < br; i++) tag[i] += x; } } void get(int t, int l, int r, int *s, int &tn) { int tl = t * BS, tr = tl + BS; for (int i = tl; i < tr; i++) if (l <= p[i] && p[i] <= r) s[++tn] = b[i] + tag[t]; } int s[2800], savl, savr; int qry(int l, int r, int k) { int bl = l / BS, br = r / BS, tn = 0; if (bl == br) get(bl, l, r, s, tn); else { int n1 = 0, n2 = 0; get(bl, l, bl * BS + BS - 1, p1, n1); get(br, br * BS, r, p2, n2); merge(p1 + 1, p1 + n1 + 1, p2 + 1, p2 + n2 + 1, s + 1); tn = n1 + n2; } l = savl; r = savr; while (l < r) { int mid = ((long long)l + r + 1) >> 1, c = lower_bound(s + 1, s + tn + 1, mid) - s - 1; for (int i = bl + 1; i < br; i++) { if (mid <= b[i * BS] + tag[i]) continue; if (b[i * BS + BS - 1] + tag[i] < mid) { c += BS; continue; } c += lower_bound(b + i * BS, b + i * BS + BS, mid - tag[i]) - (b + i * BS); } if (c < k) l = mid; else r = mid - 1; } return l; } int n, m; int main() { scanf("%d%d", &n, &m); BS = sqrt(n) * log2(n) * 0.25 + 1; for (int i = 0; i < n; i++) scanf("%d", &a[i]); n = (n - 1) / BS * BS + BS; for (int i = 0; i < n; i++) p[i] = i; for (int i = 0; i < n / BS; i++) sort(p + i * BS, p + i * BS + BS, cmp); for (int i = 0; i < n; i++) b[i] = a[p[i]]; savl = -20000; savr = 20000; for (int i = 0, op, l, r, x; i < m; i++) { scanf("%d%d%d%d", &op, &l, &r, &x); l--; r--; if (op == 2) { add(l, r, x); if (x < 0) savl += x; else savr += x; } else printf("%d\n", qry(l, r, x)); } return 0; }
- 1
信息
- ID
- 12519
- 时间
- 2000ms
- 内存
- 140MiB
- 难度
- 10
- 标签
- 递交数
- 4
- 已通过
- 1
- 上传者