D

- 题目大意

    有两种命令,Q是查询一个区间的和,C是一个区间同时增加一个数。

- 解题思路

    主要是线段树的点的更新和存储问题。每个一个数都更新到叶子节点不是明智的做法,很消耗时间。故每个节点加一个特殊量来记录增量的累加。

- 代码

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstring>
#include<stack>
using namespace std;
const int maxn = 100001;
int num[maxn];
struct node
{
	int l, r;
	long long a,s;
}t[4 * maxn];
long long ans;
void build(int l, int r, int k)
{
	int mid;
	t[k].l = l;
	t[k].r = r;
	t[k].a=0;
	if (l == r)
	    return;
    mid = (l + r) / 2;
    build(l, mid, 2 * k);
    build(mid + 1, r, 2 * k + 1);
    t[k].s=t[k*2].s+t[k*2+1].s;

}

void add(int l, int r, int x,int i)
{
	int mid;
	if(t[i].l>r||t[i].r<l)
        return;
	mid = (t[i].r + t[i].l) / 2;
	if (t[i].l>=l&&t[i].r<=r)
    {
        t[i].s+=(t[i].r-t[i].l+1)*x;
        t[i].a+=x;
        return;
    }
    if(t[i].a)
    {
        t[i*2].s+=(t[i*2].r-t[i*2].l+1)*t[i].a;
        t[i*2].a+=t[i].a;
        t[i*2+1].s+=(t[i*2+1].r-t[i*2+1].l+1)*t[i].a;
        t[i*2+1].a+=t[i].a;
        t[i].a=0;
    }
    add(l,r,x,i*2);
    add(l,r,x,i*2+1);
	t[i].s=t[i*2].s+t[i*2+1].s;
}

void findd(int l,int r, int i)
{
	int mid;
	if(t[i].l>r||t[i].r<l)
        return;
    if(t[i].l>=l&&t[i].r<=r)
    {
        ans+=t[i].s;
        return;
    }
    if(t[i].a)
    {
        t[i*2].s+=(t[i*2].r-t[i*2].l+1)*t[i].a;
        t[i*2].a+=t[i].a;
        t[i*2+1].s+=(t[i*2+1].r-t[i*2+1].l+1)*t[i].a;
        t[i*2+1].a+=t[i].a;
        t[i].a=0;
    }
    findd(l,r,i*2);
    findd(l,r,i*2+1);
	t[i].s=t[i*2].s+t[i*2+1].s;
}

int main()
{
	int n, m, a,b,c;
	char str[2];
	scanf("%d%d", &n, &m);
	for(int i=1;i<=n;i++)
        scanf("%d",&num[i]);
	build(1, n, 1);
    for(int i=1;i<=n;i++)
        add(i,i,num[i],1);
    while(m--)
    {
        scanf("%s",&str);
        if(str[0]=='C')
        {
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c,1);
        }
        if(str[0]=='Q')
        {
            ans=0;
            scanf("%d%d",&a,&b);
            findd(a,b,1);
            printf("%lld
",ans);
        }
    }
	return 0;
}

  

原文地址:https://www.cnblogs.com/alpacadh/p/8521622.html