1 条题解
-
0
#include <bits/stdc++.h> #define int long long using namespace std; const int N = 1e6 + 10, sqrtN = 1050; // 区间加,查询区间内 >= C 的元素个数 // a[i]记录每个点的值,b[i]记录每个点i所在块; // c[i]记录排序后的数组(与a[i]对应位置),用于二分查找 // 每个块i的左端点L[i]、右端点R[i], 块内标记tag[i] int n, q, 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 >> q; 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 <= q; i++) { char op; int l, r, v; cin >> op >> l >> r >> v; if (op == 'M') { 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 = 0; if (b[l] == b[r]) { // 如果l和r在同一块内 for (int j = l; j <= r; j++) { ans += (a[j] + tag[b[l]] >= v); } } else { // l ~ R[b[l]] 查询 >= v - tag[b[l]] for (int j = l; j <= R[b[l]]; j++) { ans += (a[j] + tag[b[l]] >= v); } // b[l] + 1 ~ b[r] - 1 这些块内的答案 for (int j = b[l] + 1; j <= b[r] - 1; j++) { ans += (c + R[j] + 1) - lower_bound(c + L[j], c + R[j] + 1, v - tag[j]); } // L[b[r]] ~ r 查询 >= v - tag[b[r]] for (int j = L[b[r]]; j <= r; j++) { ans += (a[j] + tag[b[r]] >= v); } } cout << ans << '\n'; } } return 0; }
- 1
信息
- ID
- 12512
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 3
- 已通过
- 1
- 上传者