数列分块

作业介绍

#include <bits/stdc++.h>
using namespace std;
const int N = 5e4+5;
#define int long long
int n,a[N],id[N],tag[N],len;
vector<int>b[N];
void update(int x) {
    b[x].clear();
    for (int i=(x-1)*len+1;id[i]==x;i++) {
        a[i]+=tag[x];
        b[x].push_back(a[i]);
    }
    tag[x] = 0;
    sort(b[x].begin(),b[x].end());
}
void add(int l,int r,int c) {
    if (id[l]==id[r]) {
        for (int i=l;i<=r;i++) {
            a[i]+=c;
        }
        update(id[l]);
    }
    else {
        for (int i=l;id[i]==id[l];i++) {
            a[i]+=c;
        }
        update(id[l]);
        for (int i=id[l]+1;i<id[r];i++) {
            tag[i]+=c;
        }
        for (int i=r;id[i]==id[r];i--) {
            a[i]+=c;
        }
        update(id[r]);
    }
}
int query(int l,int r,int c) {
    int res = 0;
    if (id[l]==id[r]) {
        for (int i=l;i<=r;i++) {
            if (a[i]+tag[id[i]]<c)res++;
        }
        return res;
    }
    else {
        for (int i=l;id[i]==id[l];i++) {
            if (a[i]+tag[id[i]]<c)res++;
        }
        for (int i=id[l]+1;i<id[r];i++) {
            int tmp = lower_bound(b[i].begin(),b[i].end(),c-tag[i])-b[i].begin();
            res+=tmp;
        }
        for (int i=r;id[r]==id[i];i--) {
            if (a[i]+tag[id[i]]<c)res++;
        }
        return res;
    }
}
signed main() {
    cin>>n;
    len = sqrt(n);
    for (int i=1;i<=n;i++) {
        cin>>a[i];
        id[i] = (i-1)/len+1;
        b[id[i]].push_back(a[i]);
    }
    for (int i=1;i<=(n-1)/len+1;i++) {
        sort(b[i].begin(),b[i].end());
    }
    for (int i=1;i<=n;i++) {
        int op,l,r,c;
        cin>>op>>l>>r>>c;
        if (op==0) {
            add(l,r,c);
        }
        else cout<<query(l,r,c*c)<<endl;
    }
    return 0;
}

题目

认领作业后才可以查看作业内容。
状态
正在进行…
题目
10
开始时间
2026-7-30 0:00
截止时间
2026-8-7 23:59
可延期
24 小时