1 条题解

  • 0
    @ 2022-4-11 19:35:09

    题意:

    nn 长度序列上 qq 次区间 +x+x , 查询区间历史 c\geq c 时长。

    题解:

    序列和时间二维平面上的矩形加柱形 c\geq c 查询,扫描线转化成区间加区间 c\geq c 查询。

    #define rep(i,a,b) for(int i=(a);i<=(b);++i)
    #define per(i,a,b) for(int i=(a);i>=(b);--i)
    #define blk(x) ((x) / bs)
    #define hob(x) ((x)*bs)
    #define eob(x) min(((x)+1) * bs - 1, n)
    using namespace std;
    
    const int maxn = 1e5, bs = 316, nb = maxn / bs + 10;
    struct block {
        ll a[maxn + 10], tag[nb + 10];
        int ovi[maxn + 10], buf1[bs + 10], buf2[bs + 10], n;
        void init(int _n) {
            n = _n;
            rep(i,0,n) ovi[i] = i;
        }
        void add(int x, int c) {
            int bx = blk(x);
            rep(i,bx + 1, blk(n)) tag[i] += c;
            int s = hob(bx), t = eob(bx);
            rep(i,x,t) a[i] += c;
            int e1 = -1, e2 = -1, p1 = 0, p2 = 0;
            rep(i,s,t) if(ovi[i] >= x) buf1[++ e1] = ovi[i]; else buf2[++ e2] = ovi[i];
            rep(i,s,t) ovi[i] = (p2 > e2 || p1 <= e1 && a[buf1[p1]] < a[buf2[p2]]) ? buf1[p1 ++] : buf2[p2 ++];
        }
        int qry(int x, int c) {
            int bx = blk(x), ans = 0;
            rep(i,blk(0),bx - 1) {
                int s = hob(i), t = eob(i);
                if(a[ovi[t]] + tag[i] < c) continue;
                if(a[ovi[s]] + tag[i] >= c) { ans += t - s + 1; continue; }
                while(s < t) {
                    int mid = (s + t) >> 1;
                    if(a[ovi[mid]] + tag[i] >= c) t = mid;
                    else s = mid + 1;
                }
                ans += eob(i) - s + 1;
            }
            rep(i,hob(bx),x) ans += a[i] + tag[bx] >= c;
            return ans;
        }
    } blker;
    
    struct node { int x, c; };
    vector< node > v[maxn + 10];
    vector< pair<node, int> > q[maxn + 10];
    
    int ans[maxn + 10], a[maxn + 10];
    
    int main() {
        int n, totQ, opt, l, r, x, p, y;
        scanf("%d %d", &n, &totQ);
        rep(i,1,n) scanf("%d", a + i);
        blker.init(totQ);
        memset(ans, -1, sizeof(ans));
        rep(qr,1,totQ) {
            scanf("%d", &opt);
            if(opt == 1) {
                scanf("%d %d %d", &l, &r, &x);
                v[l].push_back({qr, x});
                if(r != n) v[r + 1].push_back({qr, -x});
            } else if(opt == 2) {
                scanf("%d %d", &p, &y);
                q[p].push_back({{qr - 1, y}, qr});
            }
        }
        rep(i,1,n) {
            for(auto &it : v[i]) {
                blker.add(it.x, it.c);
            }
            for(auto &it : q[i]) {
                ans[it.second] = blker.qry(it.first.x, it.first.c - a[i]);
            }
        }
        rep(i,1,totQ) if(~ans[i]) printf("%d\n", ans[i]);
        return 0;
    }
    
    • 1

    信息

    ID
    2796
    时间
    2000ms
    内存
    500MiB
    难度
    6
    标签
    递交数
    1
    已通过
    1
    上传者