#8 9 10 T 求助

P3372 【模板】线段树 1

Ace2012 @ 2024-03-05 20:56:27

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e5+10;
int p,x,y,k,n,m,a[N];
struct treeNode{
    int l,r;
    LL sum;
}tree[4*N];
void build_stree(int cur,int l,int r){
    tree[cur].l=l;
    tree[cur].r=r;
    if(l==r){
        tree[cur].sum=a[l];
        return;
    }
    int mid=(l+r)>>1,lc=cur*2,rc=cur*2+1;
    build_stree(lc,l,mid);
    build_stree(rc,mid+1,r);
    tree[cur].sum=tree[lc].sum+tree[rc].sum;
}
LL query(int cur,int l,int r){
    if(l<=tree[cur].l&&tree[cur].r<=r){
        return tree[cur].sum;
    }
    int mid=tree[cur].l+tree[cur].r>>1;
    int lc=2*cur,rc=2*cur+1;
    LL sum1=0,sum2=0;
    if(l<=mid) sum1=query(lc,l,r);
    if(r>=mid+1) sum2=query(rc,l,r);
    return sum1+sum2;
}
void point_update(int cur,int pos,int val){
    if(tree[cur].l==tree[cur].r&&tree[cur].l==pos){
        tree[cur].sum+=val;
        return;
    }
    int mid=tree[cur].l+tree[cur].r>>1;
    int lc=2*cur,rc=2*cur+1;
    if(pos<=mid)point_update(lc,pos,val);
    else if(pos>=mid+1)point_update(rc,pos,val);

    tree[cur].sum=tree[lc].sum+tree[rc].sum;
}
int main(){
    cout.tie(0);
    cin.tie(0);
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    build_stree(1,1,m);
    while(m--){
        scanf("%d%d%d",&p,&x,&y);
        if(p==1){
            scanf("%d",&k);
            for(int i=x;i<=y;i++){
                point_update(1,i,k);
            }
        }else{
            printf("%lld\n",query(1,x,y));
        }
    }

    return 0;
}

70分,望大神指正


by QWQ_123 @ 2024-03-05 20:59:43

@Ace2012 这是区间加欸,你要用 lazy_tag 建议学习一下,要不然修改时间复杂度就是 O(n \log n) 比暴力 O(n) 都劣(指单次时间复杂度)


by Ace2012 @ 2024-03-06 19:31:26

谢谢 @QWQ_123 我看一下


by Ace2012 @ 2024-03-06 20:33:58

谢谢,已通过100PTS


|