1 条题解

  • 1
    @ 2026-7-27 2:52:38
    #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
    上传者