蒟蒻求改

P3372 【模板】线段树 1

YQWQ @ 2023-07-10 14:51:18

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

const int Kmax=1e5+5;

int n,m,s[Kmax]; 
ll ans;
struct tree{
    int l,r;//区间的范围 l-r
    ll zhi,lazy; 
}tre[Kmax*4+5];

void bulid(int p,int l,int r){
    tre[p].l=l,tre[p].r=r;
    if(l==r){//只有一个值 赋值 
        tre[p].zhi=s[l];
        return;
    }
    //否则 中分 两边分别处理
    // 再将得出的数累计
    int zhong=(l+r)/2;
    bulid(p*2,l,zhong);//左儿子 
    bulid(p*2+1,zhong+1,r);//右儿子 
    tre[p].zhi=tre[p*2].zhi+tre[p*2+1].zhi;
    //结果 
}

void xc(int p){
    if(tre[p].lazy){
        tre[p*2].zhi+=tre[p].lazy*(tre[p*2].r-tre[p*2].l+1);
        tre[p*2+1].zhi+=tre[p].lazy*(tre[p*2+1].r-tre[p*2+1].l+1);//为左右儿子累加值 
        tre[p*2].lazy+=tre[p].lazy;
        tre[p*2+1].lazy+=tre[p].lazy;//给左右儿子也打上标记 
        tre[p].lazy=0;
    } 
}

void change(int p,int x,int y,int k){
    if(x<=tre[p].l&&tre[p].r<=y){
        tre[p].zhi+=(ll)k*(tre[p].r-tre[p].l+1);//每份增加的值*份数 
        tre[p].lazy+=k;//打上标记
        return; 
    }
    xc(p);
    int zhong=(tre[p].l+tre[p].r)/2;  //中点 
    if(x<=zhong) change(p*2,x,y,k);
    if(y>zhong) change(p*2+1,x,y,k);//继续传递 
    tre[p].zhi=tre[p*2].zhi+tre[p*2+1].zhi;//更新总值 
} 

ll ask(int p,int x,int y){
    if(x<=tre[p].l&&tre[p].r<=y) return tre[p].zhi;
    xc(p);
    int zhong=(tre[p].l+tre[p].r)/2;
    ans=0;
    if(x<=zhong) ans+=ask(p*2,x,y);
    if(y>zhong) ans+=ask(p*2+1,x,y);
    return ans;
}

int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>s[i];
    }
    bulid(1,1,n);//建树操作   处理的位置 l r 
    int t,x,y,k;
    while(m--){
        cin>>t;
        if(t==1){
            cin>>x>>y>>k;
//          change(1,x,y,k);//修改(增加k) 
            //“ 1  ” 是开始查找的位置 
        }else{
            cin>>x>>y;
            cout<<ask(1,x,y)<<endl;
        }
    }
} 

by Schi2oid @ 2023-07-10 15:22:13

ans 设置成全局变量了


by YQWQ @ 2023-07-10 17:00:59

Orz %%% 大佬NB


by YQWQ @ 2023-07-10 17:01:19

所以为什么


|