分块

#include<bits/stdc++.h>

using namespace std;

#define endl '\n'
#define LL long long
#define x first
#define y second
// #define int long long

const LL INF=1e18;

typedef pair<int,int> PII;

const int N=100010,M=350;

int n,m,len;
LL add[M],sum[M];//段内的信息
int w[N];

int get(int x){//x这个位置隐射的是哪一块
    return x/len;
}

void change(int l,int r,int d){
    if(get(l)==get(r)){//特判一下
        for(int i=l;i<=r;i++)w[i]+=d,sum[get(i)]+=d;
    }else{
        int i=l,j=r;
        while(get(i)==get(l)) w[i]+=d,sum[get(i)]+=d,i++;//段内暴力
        while(get(j)==get(r)) w[j]+=d,sum[get(j)]+=d,j--;
        for(int k=get(i);k<=get(j);k++)sum[k]+=len*d,add[k]+=d;
    }
}

LL query(int l,int r){
    LL res=0;
    if(get(l)==get(r)){
        for(int i=l;i<=r;i++) res+=w[i]+add[get(i)];
    }else{
        int i=l,j=r;
        while(get(i)==get(l)) res+=w[i]+add[get(i)],i++;//段内暴力
        while(get(j)==get(r)) res+=w[j]+add[get(j)],j--;
        for(int k=get(i);k<=get(j);k++) res+=sum[k];
    }
    return res;
} 

void slove(){
    cin>>n>>m;
    len=sqrt(n);
    for(int i=1;i<=n;i++){
        cin>>w[i];
        sum[get(i)]+=w[i];
    }

    char op[2];
    int l,r,d;
    while(m--){
        cin>>op>>l>>r;
        if(*op=='C'){
            cin>>d;
            change(l,r,d);
        }else cout<<query(l,r)<<endl;
    }
}

signed main(){
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
    int T=1;
//    init();
    // cin>>T;
    while(T--) slove();
}
posted @ 2025-07-16 17:42  MENDAXZ  阅读(13)  评论(0)    收藏  举报