0分求调【玄关】

P3372 【模板】线段树 1

wangrunyang @ 2024-11-19 18:31:18

#include <bits/stdc++.h>
using namespace std;

#define int long long

int a[100011];

struct stree{
    int l , r , sum , add;
}t[400011];

inline int ls(int x){
    return x << 1;
}

inline int rs(int x){
    return x << 1 | 1;
}

inline int fa(int x){
    return x >> 1;
}

void spread(int p){
    if(t[p].add){
        t[ls(p)].sum += (t[ls(p)].r - t[ls(p)].l + 1) * t[p].add;
        t[ls(p)].add += t[p].add;
        t[rs(p)].sum += (t[rs(p)].r - t[rs(p)].l + 1) * t[p].add;
        t[rs(p)].add += t[p].add;
        t[p].add = 0;
    }
    return ;
}

void bulid(int p , int l , int r){
    t[p].l = l;
    t[p].r = r;
    if(l == r){
        t[p].sum = a[l];
        return ;
    }
    int mid = (l + r) >> 1;
    bulid(ls(p) , l , mid);
    bulid(rs(p) , mid + 1 , r);
    t[p].sum = t[ls(p)].sum + t[rs(p)].sum;
    return ;
}

inline int find(int p , int l , int r){
    if(t[p].l >= l && t[p].r <= r){
        return t[p].sum;
    }
//  if(t[p].l < l && t[p].r > r){
//      return 0;
//  }
    spread(p);
    int ret = 0;
    int mid = (t[p].l + t[p].r) >> 1;
    if(l <= mid) ret += find(ls(p) , l , r);
    if(r > mid) ret += find(rs(p) , l , r);
    return ret;
}

void add(int l , int r , int p , int x){
    if(t[p].l >= l && t[p].r <= r){
        t[p].sum += (t[p].r - t[p].l + 1) * x;
        t[p].add += x;
        return ;
    }
    spread(p);
    int mid = (t[p].l + t[p].r) >> 1;
    if(l <= mid) add(ls(p) , l , r , x);
    if(r > mid) add(rs(p) , l , r , x);
    t[p].sum = t[ls(p)].sum + t[rs(p)].sum;
    return ;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n , m;
    cin >> n >> m;
    for(int i = 1;i <= n;i++){
        cin >> a[i];
    }
    bulid(1 , 1 , n);
    for(int i = 1;i <= m;i++){
        int op;
        cin >> op;
        if(op == 1){
            int l , r , _add;
            cin >> l >> r >> _add;
            add(l , r , 1 , _add);
        }
        else{
            int l , r;
            cin >> l >> r;
            cout << find(1 , l , r) << "\n";
        }
//      for(int j = 1;j <= n * 4;j++){
//          cout << j << " " << t[j].sum << " " << t[j].add << " " << t[j].l << " " << t[j].r << "\n";
//      }
//      cout << "\n\n\n";
    }
    return 0;
}

|