当前位置:首页 » IOS开发技术

bzoj 3212 Pku3468 A Simple Problem with Integers

2017-09-23 20:21 本站整理 浏览(12)

3212: Pku3468 A Simple Problem with Integers

Time Limit: 1 Sec  Memory Limit: 128 MB

Description

You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval. 

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000. 
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000. 
Each of the next Q lines represents an operation. 
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000. 
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab. 

Output

You need to answer all Q commands in order. One answer in a line. 

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

HINT

The sums may exceed the range of 32-bit integers. 

Source

  Tips:   非常裸的线段树的区间操作;   Code:
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
int n,m,a[1000008];
long long tree[4000008],mark[1000008];
char s[10];
 
void build(int l,int r,int v){
    if(l==r){
        tree[v]=a[l];
        return;
    }
    int mid=(l+r) >> 1;
    build(l,mid,v<<1);
    build(mid+1,r,(v<<1)+1);
    tree[v]=tree[v<<1]+tree[(v<<1)+1];
}
 
void add(int l,int r,int x,int y,int z,int v){
    if(l==x&&r==y){
        mark[v]+=z;
        return;
    }
    int mid=(l+r)>>1;
    mark[v<<1]+=mark[v];
    mark[(v<<1)+1]+=mark[v];
    mark[v]=0;
    if(mid>=y)  add(l,mid,x,y,z,v<<1);
    if(mid<x)  add(mid+1,r,x,y,z,(v<<1)+1);
    if(mid>=x&&mid<y){
        add(l,mid,x,mid,z,v<<1);
        add(mid+1,r,mid+1,y,z,(v<<1)+1);
    }
    tree[v]=tree[v<<1]+mark[v<<1]*(mid-l+1)+tree[(v<<1)+1]+mark[(v<<1)+1]*(r-mid);
}
 
long long query(int l,int r,int x,int y,int v){
    long long ans=0;
    if(l==x&&r==y){
        ans=tree[v]+mark[v]*(r-l+1);
        return ans;
    }
    mark[v<<1]+=mark[v];
    mark[(v<<1)+1]+=mark[v];
    mark[v]=0;
    int mid=(l+r)>>1;
    if(mid>=y)  ans=query(l,mid,x,y,v<<1);
    if(mid<x)  ans=query(mid+1,r,x,y,(v<<1)+1);
    if(mid>=x&&mid<y)  ans=query(l,mid,x,mid,v<<1)+query(mid+1,r,mid+1,y,(v<<1)+1);
    tree[v]=tree[v<<1]+mark[v<<1]*(mid-l+1)+tree[(v<<1)+1]+mark[(v<<1)+1]*(r-mid);
    return ans;
}
 
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    build(1,n,1);
    for(int i=1;i<=m;i++){
        scanf("%s",s);
        int x,y,z;
        if(s[0]=='C'){
            scanf("%d%d%d",&x,&y,&z);
            if(x>y) swap(x,y);
            add(1,n,x,y,z,1);
        }else{
            scanf("%d%d",&x,&y);
            if(x>y) swap(x,y);
            printf("%lld\n",query(1,n,x,y,1));
        }
    }
}