求调qwq

P3372 【模板】线段树 1

Daydayup_Olivia @ 2024-02-29 13:35:17

#include<bits/stdc++.h>
using namespace std;
int n,m;
const int N=1e5+10;
int num[N];
struct aa{
    int l,r;
    long long sum;
    int add;
}a[N*4];
int val[N]; 
void build(int i,int l,int r){
    a[i].l=l;
    a[i].r=r;
    if(l==r){//是叶节点 
        a[i].sum=val[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(i<<1,l,mid);
    build(i<<1|1,mid+1,r);
    a[i].sum=a[i<<1].sum+a[i<<1|1].sum;
}
long long query(int i,int l,int r){

    if(a[i].l==l&&a[i].r==r){
        return a[i].sum;
    }
    int mid=(a[i].l+a[i].r)>>1;
    if(mid>=r){
        return query(i<<1,l,r);
    }else if(mid<l){
        return query(i<<1|1,l,r);
    }
    return query(i<<1,l,mid)+query(i<<1|1,mid+1,r);
}
void updata(int i,int x,int y){//单点修改 
    if(a[i].l==a[i].r){
        a[i].sum+=y;
        return;
    }
    int mid=(a[i].l+a[i].r)>>1;
    if(x<=mid) updata(i<<1|1,x,y);
    else updata(i<<1|1,x,y);
    a[i].sum=a[i<<1].sum+a[i<<1|1].sum;
}
void down(int i){
    if(a[i].add){
        long long x=a[i].add;
        a[i<<1].add+=x;
        a[i<<1|1].add+=x;
        a[i<<1].sum+=(a[i<<1].r-a[i<<1].l+1)*x;
        a[i<<1|1].sum+=(a[i<<1|1].r-a[i<<1|1].l+1)*x;
        a[i].add=0;
    }
}
void up(int i){
    a[i].sum=0;
    if(a[i<<1].l){
        a[i].sum+=a[i<<1].sum;
    }
    if(a[i<<1|1].l){
        a[i].sum+=a[i<<1|1].sum;
    }
}
void uupdata(int i,int l,int r,int add){//区间修改long long
    if(a[i].l==l&&a[i].r==r){
        a[i].sum+=(a[i].r-a[i].l+1)*add;
        a[i].add+=add;
        return;
    }
    down(i);
    int mid=(a[i].l+a[i].r)>>1;
    if(mid>=r){
        uupdata(i<<1,l,r,add);

    }else if(mid<l){
        uupdata(i<<1|1,l,r,add);
    }else{
        uupdata(i<<1,l,mid,add);
        uupdata(i<<1|1,mid+1,r,add);
    }
    up(i);
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>val[i];
    }
    build(1,1,n);
    for(int i=1;i<=m;i++){
        int tmp;
        cin>>tmp;
        if(tmp==1){
            int x;
            int k;
            int y;
            cin>>x>>y>>k;
            uupdata(1,x,y,k);
        }
        if(tmp==2){
            int x;
            int y;
            cin>>x>>y;
            cout<<query(1,x,y)<<endl;
        }
    } 
    return 0;
}

by The_Soloist @ 2024-02-29 20:28:53

第44行就开始有问题吧,if else 后面的语句一样

if(x<=mid) updata(i<<1|1,x,y);
    else updata(i<<1|1,x,y);

还有这个updata应该看意思是区间修改的作用,但是好像 i 是定义的树中结点的编号 ,但是实际上看下来好像每次都遍历了每个根节点才加上的

if(a[i].l==a[i].r){
        a[i].sum+=y;
        return;
    }

这样的时间复杂度应该算下来是 O(N^2)吧?应该提前在全部能选的地方就停下了就好了吧...

不懂><


by Daydayup_Olivia @ 2024-03-11 12:53:10

@The_Soloist 谢谢您!(回复不及时 抱歉! #^_^#


|