求助,刚学,不是很懂,WA了最后三点
查看原帖
求助,刚学,不是很懂,WA了最后三点
111672
茄与你皆刀楼主2020/7/26 20:28
#include<bits/stdc++.h>
using namespace std;
long long n,m,x,y,k,a1;
long long tree[1000200]/*线段树模型*/, tag[1000050];// 懒惰标志 
long long  a[1000050];//数组模型 
void build(int rt, int l, int r)
{
	if (l == r) {
		tree[rt] = a[l];
		tag[rt] = 0;//将懒惰标志清零(初始化)
		return;
	}
	int mid = (l + r) >> 1;
	build(rt * 2, l, mid);//递归左儿子 
	build(rt * 2 + 1, mid + 1, r);//递归右儿子 
	tree[rt] = tree[rt * 2] + tree[rt * 2 + 1]; 
}//构造二叉树模型 
void down(int rt, int l, int mid, int r)
{
	int val = tag[rt];
	tag[rt] = 0;
	tree[rt * 2] += val * (mid - l + 1);
	tag[rt * 2] += val;
	tree[rt * 2 + 1] += val * (r - mid);
	tag[rt * 2 + 1] += val; 
}
void update(int rt, int l, int r, int x, int y, int val)//(x,y)为需要更新的区间,val为需要加的值
{
	if (y < l || x > r) return;//不在此区间,跳过 
	if (x <= l && r <= y)/*在此区间*/ {
		tree[rt] += val * (r - l + 1);//更新线段树模型 
		tag[rt] += val;//更新懒惰标志的值 
		return;
	}
	int mid = (l + r) >> 1;
	down(rt, l, mid, r);//调用懒惰标志下放函数 
	update(rt * 2, l, mid, x, y, val);//递归左儿子
	update(rt * 2 + 1,  mid + 1, r, x, y, val);//递归右儿子 
	tree[rt] = tree[rt * 2] + tree[rt * 2 + 1];
}//更新

long long query(long long rt, long long l, long long r, long long x, long long y)
{
	if (y < l || r < x) return 0;//不在此区间,跳过 
	if (x <= l && r <= y) return tree[rt];/*在此区间*/
	int mid = (l + r) >> 1;
	down(rt, l, mid, r);
	return query(rt * 2, l, mid, x, y) + query(rt * 2 + 1, mid + 1, r, x, y);
}//查询 
int main()
{
    scanf("%d%d",&n,&m);
    for(long long i=1;i<=n;i++)    scanf("%d",&a[i]);
    build(1,1,n);
    for(long long i=1;i<=m;i++)
    {
        scanf("%d",&a1);
        if(a1==1){
            scanf("%d%d%d",&x,&y,&k);
            update(1,1,n,x,y,k);
        }
        else{
            scanf("%d%d",&x,&y);
            printf("%d\n",query(1,1,n,x,y));
        }
    }
    return 0;
}
2020/7/26 20:28
加载中...