POJ 3468 A Simple Problem with Integers(线段树)

来源:互联网 发布:中医诊断软件 编辑:程序博客网 时间:2024/06/01 07:40

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.

区间更新 区间查询模板题, 从杭电上拉成专题 乱码不说 连The sums may exceed the range of 32-bit integers.这句话都没有
心鸡儿痛
主要是 输入那%lld忘改了一直wa 想哭 ,其他没啥坑了

code:

#include <iostream>//#include <bits/stdc++.h>#include <cstdio>#include <string.h>using namespace std;#define lchild left, mid, root<<1#define rchild mid+1, right, root<<1|1#define maxn 200000long long int sum[maxn<<2];long long int lazy[maxn<<2];void update(int root){    sum[root] = sum[root<<1]+sum[root<<1|1];}void lazyup(int root,int left, int right){    if (lazy[root])    {        lazy[root<<1] += lazy[root];        lazy[root<<1|1] += lazy[root];        int mid = (left+right)>>1;        int leftlen = mid-left+1;        int rightlen = right-mid;        sum[root<<1] += lazy[root]*leftlen;        sum[root<<1|1] += lazy[root]*rightlen;        lazy[root] = 0;    }}void build (int left, int right, int root){    lazy[root] = 0;    if (left==right){        scanf("%lld",&sum[root]);        //printf ("%d %d\n",root,sum[root]);        return;    }    int mid = (left+right)>>1;    build(lchild);      //递归建立左右子树    build(rchild);    update(root);    //更新父节点的sum,计算left~right这个区间的士兵数量}void operate(int left, int right, int root, int l, int r, int op){    if (l<=left&&r>=right){     //如果找到进行操作        sum[root] += (right-left+1)*op;        lazy[root] += op;        return;    }    lazyup(root, left, right);    int mid = (left+right)>>1;    if (l<=mid)        operate(lchild, l, r,op);    //如果寻找节点在中点之前,在左区间二分继续找    if(r>mid)        operate(rchild, l,r,op);     //否则右区间二分继续找    update(root);    //更新节点}long long int inquery(int l, int r, int left, int right, int root){    if (l<=left&&r>=right)  //当前节点的区间在所查询的区间之内,返回区间和值        return sum[root];    lazyup(root,left, right);    int mid = (left+right)>>1;    long long int ans=0;    if (l<=mid)        ans += inquery(l,r,lchild);    if (r>mid)        ans += inquery(l, r,rchild);    return ans;}int main(){    int n,i,j,k,m;    while (~scanf("%d%d",&n,&m))    {        memset(sum,0,sizeof(sum));        build(1,n,1);        int x,y;        char op;        long long int ans;       while (m--)        {            scanf(" %c",&op);            if (op=='Q')            {                scanf("%d%d",&i,&j);                ans = inquery(i,j,1,n,1);                printf ("%lld\n",ans);            }            else            {                scanf("%d%d%d",&i,&j,&k);                operate(1,n,1,i,j,k);            }        }    }    return 0;}
原创粉丝点击