刚学2天线段树,只能过样例,求调

P3372 【模板】线段树 1

TsH_GD @ 2022-11-12 22:51:41

#include<iostream>
#include<cstdio>

using namespace std;

const long long maxn=1e5+10;

long long n,m;
long long a[maxn];

struct segment_tree{

    struct Node{
        long long l,r;
        long long sum;
        long long lz;
    }tr[maxn*4];

    void build(long long p,long long l,long long r){
        tr[p]={l,r,0,0};

        if(l==r){
            tr[p].sum=a[l];
            return ;
        }

        long long mid=l+r>>1;
        build(p<<1,l,mid);
        build(p<<1|1,mid+1,r);
    }

    void add(long long p,long long l,long long r,long long k){
        if(tr[p].r<=r&&tr[p].l>=l){
            tr[p].sum+=k*(tr[p].r-tr[p].l+1);
            tr[p].lz+=k;
            return ;
        }

        pushdown(p);

        if(tr[p<<1].r>=l) add(p<<1,l,r,k);
        if(tr[p<<1|1].l<=r) add(p<<1|1,l,r,k);

        tr[p].sum=tr[p<<1].sum+tr[p<<1|1].sum;
    }

    void pushdown(long long p){
        if(tr[p].lz!=0){
            tr[p<<1].lz+=tr[p].lz;
            tr[p<<1|1].lz+=tr[p].lz;

            long long mid=tr[p].l+tr[p].r>>1;
            tr[p<<1].sum+=tr[p].lz*(mid-tr[p<<1].l+1);
            tr[p<<1|1].sum+=tr[p].lz*(tr[p<<1|1].r-mid);
            tr[p].lz=0;
        }
        return ;
    }

    long long mysearch(long long i,long long l,long long r){
        if(tr[i].l>=l && tr[i].r<=r)
            return tr[i].sum;
        if(tr[i].r<l || tr[i].l>r)  return 0;
        pushdown(i);
        long long s=0;
        if(tr[i*2].r>=l)  s+=mysearch(i*2,l,r);
        if(tr[i*2+1].l<=r)  s+=mysearch(i*2+1,l,r);
        return s;
    }

}ST;

int main(){
    scanf("%lld %lld",&n,&m);

    for(long long i=1;i<=n;i++) 
        scanf("%lld",&a[i]);

    ST.build(1,1,n);

    for(long long i=1;i<=m;i++){
        long long op;
        scanf("%lld",&op);
        if(op==1){
            long long x,y;
            long long k;
            scanf("%lld %lld %lld",&x,&y,&k);
            ST.add(1,x,y,k);
        }
        else{
            long long x,y;
            scanf("%lld %lld",&x,&y);
            printf("%lld\n",ST.mysearch(1,x,y));
        }
    }
}

by Jerrlee✅ @ 2022-11-12 22:53:22

orz GD

但是这题可以用树状数组做(


by TsH_GD @ 2022-11-12 22:54:18

@Jerrlee✅ 想学线段树


by TsH_GD @ 2022-11-12 22:54:41

@Jerrlee✅ 你会调吗


by TsH_GD @ 2022-11-12 22:56:17

@yukari1735

您看看有救吗


by ssytxy2024 @ 2022-11-12 22:56:27

#include<bits/stdc++.h>
using namespace std;
int n,m;
int opt,x,y,k;
struct node{
    long long sum;
    int l,r;
    int tag;
};
node T[400005];
int a[100005];
void f(int p,int k){
    T[p].sum+=(T[p].r-T[p].l+1)*k;
    T[p].tag+=k; 
}
void push_down(int p){
    f(p*2,T[p].tag);
    f(p*2+1,T[p].tag);
    T[p].tag=0;
}
void build(int l,int r,int p){
    T[p].l=l,T[p].r=r;
    if(l==r){
        T[p].sum=a[l];
        return ;
    }
    int mid=(l+r)/2;
    build(l,mid,p*2);
    build(mid+1,r,p*2+1);
    T[p].sum=T[p*2].sum+T[p*2+1].sum;
}
long long query(int l,int r,int p){
    long long ans=0;
    if(l<=T[p].l&&r>=T[p].r){
        return T[p].sum;
    }
    int mid=(T[p].l+T[p].r)/2;
    push_down(p);
    if(l<=mid) ans+=query(l,r,p*2);
    if(r>mid) ans+=query(l,r,p*2+1);
    return ans;
}
void add(int x,int y,int ad,int p){
    if(x<=T[p].l&&T[p].r<=y){
        T[p].sum+=(T[p].r-T[p].l+1)*ad;
        T[p].tag+=ad;
        return ;
    }
    push_down(p);
    int mid=(T[p].l+T[p].r)/2;
    if(x<=mid) add(x,y,ad,p*2);
    if(y>mid) add(x,y,ad,p*2+1);
    T[p].sum=T[p*2].sum+T[p*2+1].sum;
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    build(1,n,1);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&opt,&x,&y);
        if(opt==1){
            scanf("%d",&k);
            add(x,y,k,1);
        }
        else{
            printf("%lld\n",query(x,y,1));
        }
    }
    return 0;
}

我的代码和你的差不多一样,看一下对你有没有帮助。


by Jerrlee✅ @ 2022-11-12 22:57:35

我是瞎子,看不出来错哪儿/kx


by 鸽子爱咕咕 @ 2022-11-12 23:00:31


by Flanksy @ 2022-11-12 23:03:08

确实build没pushup


by TsH_GD @ 2022-11-13 08:08:27

@鸽子爱咕咕 OK 过了谢谢


|