70pts 求救!!!
查看原帖
70pts 求救!!!
690312
__Moogy__楼主2022/11/24 22:33
#include<bits/stdc++.h>
using namespace std;
#define ENDL putchar('\n')
typedef long long ll;
inline void read(ll &x);
inline void write(ll x);
#define lazy lz 

#define ls(p) (p)<<1
#define rs(p) (p)<<1|1

struct Tree{
	int l,r,sum,lz;
};

vector<Tree> tree;
vector<ll> input;
ll n,m;
ll sign,x,k,y;

inline void build(ll i,ll l,ll r){//递归建树
    tree[i].l=l;
	tree[i].r=r;
    if(l==r){//如果这个节点是叶子节点
        tree[i].sum=input[l];
        return;
    }
    else{
	    ll mid=(l+r)>>1;
	    build(ls(i),l,mid);//构造左子树
	    build(rs(i),mid+1,r);//构造右子树
	    tree[i].sum=tree[ls(i)].sum+tree[rs(i)].sum;//刚才我们发现的性质
	}
}

void push_down(ll i){
    if(tree[i].lz!=0){
	    tree[ls(i)].sum+=(tree[ls(i)].r-tree[ls(i)].l+1)*tree[i].lz;
	    tree[rs(i)].sum+=(tree[rs(i)].r-tree[rs(i)].l+1)*tree[i].lz;
        tree[ls(i)].lz+=tree[i].lz;//左右儿子分别加上父亲的lz
        tree[rs(i)].lz+=tree[i].lz;
        tree[i].lz=0;//父亲lz归零
    }
}

void add(ll i,ll l,ll r,ll k){
    if(tree[i].l==l&&tree[i].r==r){
        tree[i].sum+=(r-l+1)*k;
        tree[i].lz+=k;
    }
    else{
		push_down(i);//向下传递
	    ll mid=(tree[i].l+tree[i].r)>>1;
	    if(r<=mid) add(ls(i),l,r,k);
	    else if(l>mid) add(rs(i),l,r,k);
	    else add(ls(i),l,mid,k),add(rs(i),mid+1,r,k);
	    tree[i].sum=tree[ls(i)].sum+tree[rs(i)].sum;
	}
}

inline ll sum(ll i,ll l,ll r){
    if(tree[i].l==l&&tree[i].r==r) return tree[i].sum;
    push_down(i);
    ll mid=(tree[i].l+tree[i].r)>>1;
    if(r<=mid) return sum(ls(i),l,r);
    else if(l>mid) return sum(rs(i),l,r);
    else return sum(ls(i),l,mid)+sum(rs(i),mid+1,r);
}

signed main(){
//	freopen("P3372_8.in","r",stdin);
//	freopen("P3372_8.out","w",stdout);
	read(n),read(m);
	tree.resize(4*n+5);
	input.resize(n+5);
	for(ll i=1;i<=n;i++){
		read(input[i]);
	}
	build(1,1,n);
	while(m--){
		read(sign),read(x),read(y);
		if(sign==1){
			read(k);
			add(1,x,y,k);
		}
		else{
			write(sum(1,x,y));
			ENDL;
		} 
	}
}

inline void read(ll &x){
	char c=getchar();
	ll abs_val=0;
	ll sign=1;
	while(!isdigit(c)){
		if(c=='-') sign=-1;
		c=getchar();
	}
	while(isdigit(c)){
		abs_val=(abs_val<<1)+(abs_val<<3)+(c^48);
		c=getchar();
	}
	x=sign*abs_val;
}

inline void write(ll x){
	if(x<0){
		putchar('-');
		x=-x;
	}
	if(x>=10) write(x/10);
	putchar(x%10+48);
}
2022/11/24 22:33
加载中...