分塊9講:

三、 求區間x前驅;

1、vector版本:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <cstdio>
#include <string>

using namespace std;
typedef long long ll;

#define _rep(i, a, b) for (int i = a; i <= b; i++)
#define _for(i, a, b) for (int i = a; i < b; i++)

const int maxn = 1e5 + 10;
const int inf = 0x3f3f3f3f;

ll read() {
    ll x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9') {
        if(ch == '-') {
            f = -1;
        }
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9') {
        x = x*10 + (ch - '0');
        ch = getchar();
    }
    return x*f;
}
int blo;
int n;
int bl[maxn],atag[maxn];
int ac[maxn];
vector<int > vec[maxn];

void reset(int x) {
    vec[x].clear();
    _rep(i, (x-1)*blo +1, min(x*blo,n)) {
        vec[x].push_back(ac[i]);
    }
    sort(vec[x].begin(), vec[x].end());
}

void add(int l, int r, int c) {
    _rep(i, l, min(bl[l]*blo, r)) {
        ac[i] += c;
    }
    reset(bl[l]);
    if(bl[l] != bl[r]) {
        _rep(i, (bl[r]-1)*blo+1, r){
            ac[i] += c;
        }
        reset(bl[r]);
    }
    _rep(i, bl[l]+1, bl[r]-1) {
        atag[i] += c;
    }
}

int query(int l, int r, int c) {
    int max_=  -inf;
    _rep(i, l, min(bl[l]*blo, r)) {
        if(ac[i] + atag[bl[l]] < c) {
            max_ = max(max_, ac[i]+atag[bl[l]]);
        }
    }
    if(bl[l] != bl[r]) {
        _rep(i, (bl[r]-1)*blo+1, r) {
            if(ac[i] + atag[bl[r]] < c) {
                max_ = max(max_, ac[i]+atag[bl[r]]);
            }
        }
    }
    _rep(i, bl[l]+1, bl[r]-1) {
        int x = c- atag[i];
        int pos = lower_bound(vec[i].begin(), vec[i].end(), x) - vec[i].begin();
        if(vec[i][pos] < x) {
            max_ = max(max_, vec[i][pos] + atag[i]);
        }
        else if(pos != 0){
            max_ = max(max_, vec[i][pos-1]+atag[i]);
        }
        if(pos) {
            max_ = max(max_, vec[i][pos - 1] + atag[i]);
        }
    }
    return max_;
}

int main() {
//    freopen("a1.in", "r", stdin);
//    freopen("out.txt", "w", stdout);
    n = read();
    blo = sqrt(n);
    _rep(i, 1, n) ac[i] = read();
    _rep(i, 1, n) {
        bl[i] = (i-1)/blo +1;
        vec[bl[i]].push_back(ac[i]);
    }
    _rep(i, 1, bl[n]) {
        sort(vec[i].begin(), vec[i].end());
    }

    _rep(i, 1, n) {
        int opt, l, r, c;
        opt = read(); l = read(); r = read(); c = read();
        if(!opt) {
            add(l, r, c);
        }
        else {
            int ans = query(l, r, c);
            if(ans != -inf) {
                printf("%d\n", ans);
            }
            else {
                printf("-1\n");
            }
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章