1 条题解
-
1
#include <bits/stdc++.h> #define int long long using namespace std; const int N = 1e5 + 10, sqrtN = 350; // 区间加,查询区间前驱 // a[i]记录每个点的值,b[i]记录每个点i所在块; // c[i]记录排序后的数组(与a[i]对应位置),用于二分查找前驱 // 每个块i的左端点L[i]、右端点R[i], 块内标记tag[i] int n, a[N], b[N], c[N], L[sqrtN], R[sqrtN], tag[sqrtN]; signed main() { ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; c[i] = a[i]; } int B = sqrt(n), cnt = (n + B - 1) / B; // B为每块的长度,cnt为总块数 for (int i = 1; i <= n; i++) { b[i] = (i - 1) / B + 1; } for (int i = 1; i <= cnt; i++) { L[i] = (i - 1) * B + 1; R[i] = min(i * B, n); sort(c + L[i], c + R[i] + 1); } memset(tag, 0, sizeof(tag)); for (int i = 1; i <= n; i++) { int op, l, r, v; cin >> op >> l >> r >> v; if (op == 0) { if (b[l] == b[r]) { // 如果l和r在同一块内 for (int j = l; j <= r; j++) a[j] += v; for (int j = L[b[l]]; j <= R[b[l]]; j++) c[j] = a[j]; sort(c + L[b[l]], c + R[b[l]] + 1); } else { for (int j = l; j <= R[b[l]]; j++) a[j] += v; for (int j = L[b[l]]; j <= R[b[l]]; j++) c[j] = a[j]; sort(c + L[b[l]], c + R[b[l]] + 1); for (int j = b[l] + 1; j <= b[r] - 1; j++) tag[j] += v; for (int j = L[b[r]]; j <= r; j++) a[j] += v; for (int j = L[b[r]]; j <= R[b[r]]; j++) c[j] = a[j]; sort(c + L[b[r]], c + R[b[r]] + 1); } } else { int ans = -1; if (b[l] == b[r]) { // 如果l和r在同一块内 for (int j = l; j <= r; j++) { int val = a[j] + tag[b[l]]; if (val < v && val > ans) ans = val; } } else { for (int j = l; j <= R[b[l]]; j++) { int val = a[j] + tag[b[l]]; if (val < v && val > ans) ans = val; } for (int j = b[l] + 1; j <= b[r] - 1; j++) { auto it = lower_bound(c + L[j], c + R[j] + 1, v - tag[j]); if (it != c + L[j]) { it--; int val = *it + tag[j]; if (val < v && val > ans) ans = val; } } for (int j = L[b[r]]; j <= r; j++) { int val = a[j] + tag[b[r]]; if (val < v && val > ans) ans = val; } } cout << ans << '\n'; } } return 0; }
- 1
信息
- ID
- 471
- 时间
- 1500ms
- 内存
- 256MiB
- 难度
- 6
- 标签
- 递交数
- 34
- 已通过
- 11
- 上传者