F

Description

给出了一个序列,你需要处理如下两种询问。

"C a b c"表示给[a, b]区间中的值全部增加c (-10000 ≤ c ≤ 10000)。

"Q a b" 询问[a, b]区间中所有值的和。

Input

第一行包含两个整数N, Q。1 ≤ N,Q ≤ 100000.

第二行包含n个整数,表示初始的序列A (-1000000000 ≤ Ai ≤ 1000000000)。

接下来Q行询问,格式如题目描述。

Output

对于每一个Q开头的询问,你需要输出相应的答案,每个答案一行。

Sample Input

10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4

Sample Output

4
55
9
15

AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=100000;
int num[maxn];
struct node
{
    int l,r;//区间的左右端点
    long long sum;//区间上的和
    long long  Inc;//区间上增量的累加
}tree[maxn*3];


void build(int i,int l,int r)//建立一个线段树
{
    tree[i].l=l;
    tree[i].r=r;
    tree[i].Inc=0;
    if(l==r)
    {
        tree[i].sum=num[l];
    return;
    }
        int mid=(l+r)>>1;
        build(i<<1,l,mid);//build(i*2,l,mid)
        build(i<<1|1,mid+1,r);//build(i*2+1,mid+1,r)
        tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum;//tree[i].sum=tree[i*2].sum+tree[i*2+1].sum;
}

void Add(int i,int a,int b,long long c)//在节点i的区间(a,b)上增加c
{
    if(tree[i].l==a&&tree[i].r==b)
    {
         tree[i].Inc+=c;
    return;
    }
   tree[i].sum+=c*(b-a+1);
   int mid=(tree[i].l+tree[i].r)>>1;//int mid=(tree[i].l+tree[i].r)/2;
   if(b<=mid) Add(i<<1,a,b,c);//Add(i*2,a,b,c);
   else if(a>mid) Add(i<<1|1,a,b,c);//Add(i*2+1,a,b,c);
   else
   {
       Add(i<<1,a,mid,c);//Add(i*2,a,mid,c)
       Add(i<<1|1,mid+1,b,c);//Add(i*2+1,mid+1,b,c);
   }
}

long long query(int i,int a,int b)//查询a-b的总和
{
    if(tree[i].l==a&&tree[i].r==b)
        return tree[i].sum+(b-a+1)*tree[i].Inc;
    tree[i].sum+=(tree[i].r-tree[i].l+1)*tree[i].Inc;
    int mid=(tree[i].l+tree[i].r)>>1;//mid=(tree[i].l+tree[i].r)/2;
    Add(i<<1,tree[i].l,mid,tree[i].Inc);
    Add(i<<1|1,mid+1,tree[i].r,tree[i].Inc);
    tree[i].Inc=0;
    if(b<=mid)  return query(i<<1,a,b);
    else if(a>mid) return query(i<<1|1,a,b);
    else  return query(i<<1,a,mid)+query(i<<1|1,mid+1,b);
}

int main()
{
 int  n,q;
 int i;
 int a,b,c;
 char ch;
 while(scanf("%d%d",&n,&q)!=EOF)
 {
     for(i=1;i<=n;i++)
        scanf("%d",&num[i]);
     build(1,1,n);
     for(i=1;i<=q;i++)
     {
         cin>>ch;
          if(ch=='C')
          {
              scanf("%d%d%d",&a,&b,&c);
              Add(1,a,b,c);
          }
          else
          {
              scanf("%d%d",&a,&b);
              printf("%lld
",query(1,a,b));
          }
     }
 }
     return 0;
 }



原文地址:https://www.cnblogs.com/lbyj/p/5696294.html