10分求调

P3372 【模板】线段树 1

yehuadonghui @ 2024-01-03 20:44:14

#include <bits/stdc++.h>
using namespace std;
const int maxn =  100010;

int a[maxn+2];
struct tree{
    int l,r;
    long long pre,add;
}t[4*maxn+2];

void build(int p,int l,int r)
{

    t[p].l=l;
    t[p].r=r;
    if(l==r) {
        t[p].pre=a[l];
        return ;
    } 
    int mid= (l+r)>>1;

    build(p*2,l,mid);
    build(p*2+1,mid+1,r);

    t[p].pre=t[p*2].pre+t[p*2+1].pre;   
}//建树

void spread(int p){
    if(t[p].add) {
        t[p*2].pre+=t[p].add*(t[p*2].r-t[p*2].l+1);
        t[p*2+1].pre=t[p].add*(t[p*2+1].r-t[p*2+1].l+1);
        t[p*2].add+=t[p].add;
        t[p*2+1].add+=t[p].add;
        t[p].add=0;

    }

}//懒标记。

void change(int p,int x,int y,int z)//区间修改
{
    if(x<=t[p].l && y>=t[p].r) {
        t[p].pre+=(long long )z*(t[p].r-t[p].l+1);
        t[p].add+=z;
        return ;
    }

    spread(p);
    int mid= (t[p].l+t[p].r)>>1;
    if(x<=mid) change(p*2,x,y,z);
    if(y>mid) change(p*2+1,x,y,z);

    t[p].pre=t[p*2].pre+t[p*2+1].pre;

}

long long ask(int p,int x,int y)//区间查询
{
    if(x<=t[p].l && y>=t[p].r) {
        return t[p].pre;
    } 
    spread(p);
    int mid= (t[p].l+t[p].r) >>1;
    long long ans=0;

    if(x<=mid) ans+=ask(p*2,x,y);
    if(y>mid) ans+=ask(p*2+1,x,y);

    return ans;

}

int main()
{
    int n,m;
    cin>>n>>m;

    for (int i=1;i<=n;i++) {
        cin>>a[i];
    }
    build(1,1,n);

    for (int i=1;i<=m;i++){
        int o,x,y,k;

        cin>>o;

        if(o==1) {
            cin>>x>>y>>k;
            change(1,x,y,k);

        }
        else {
            cin>>x>>y;
            cout<<ask(1,x,y)<<endl;
        }
    }

}

by njz1234 @ 2024-02-09 00:40:10

t[p*2+1].pre=t[p].add*(t[p*2+1].r-t[p*2+1].l+1);

这个地方=要改成+=


by yehuadonghui @ 2024-02-16 00:46:19

@njz1234 感谢大佬


|