线段树求调
查看原帖
线段树求调
545507
pl_cosmonaut楼主2022/4/9 12:18
#include<bits/stdc++.h>
using namespace std;
struct t{
    long long sum,add;
}tree[400001];
int n,m;
int a[100001];


void pushup(int x){
    tree[x].sum=tree[x*2].sum+tree[x*2+1].sum;
}

void spread(int index,int l,int r){
	int mid=(l+r)/2;
	if(tree[index].add){
		tree[index*2].sum+=(mid-l+1)*tree[index].add;
		tree[index*2+1].sum+=(r-mid)*tree[index].add;
		tree[index*2].add+=tree[index].add;
		tree[index*2+1].add+=tree[index].add;
		tree[index].add=0;
	}
}

void build(int index,int l,int r){
    if(l==r){
        tree[index].sum=a[l]; 
        return;
    }
    int mid=(l+r)/2;
    build(index*2,l,mid);
    build(index*2+1,mid+1,r);
    pushup(index);
}

void modify(int index,int l,int r,int x,int y,int k){
	if(x<=l && y>=r){
		tree[index].sum+=(long long)(l-r+1)*k;
		tree[index].add+=k;
		return;
	}
	spread(index,l,r);
	int mid=(l+r)/2;
	if(l<=mid){
		modify(index*2,1,mid,x,y,k);
	}
	if(r>mid){
		modify(index*2+1,mid+1,r,x,y,k);
	}
	pushup(index);
}

long long query(int index,int l,int r,int x,int y){
    if(x<=l && y>=r){
        return tree[index].sum;

    }
    long long mid=(l+r)/2,ret=0;
    if(x<=mid){
        ret+=query(index*2,l,mid,x,y);
    }
    if(y>mid){
        ret+=query(index*2+1,mid+1,r,x,y);
    }
    return ret;
}

int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    build(1,1,n);
    int type;
    for(int i=1;i<=m;i++){
    	cin>>type;
    	if(type==1){
    		int x,y,k;
    		cin>>x>>y>>k;
    		modify(1,1,n,x,y,k);
		}
		if(type==2){
			int x,y;
			cin>>x>>y;
			cout<<query(1,1,n,x,y)<<endl;
		}
	}
    return 0;
}
2022/4/9 12:18
加载中...