LightOJ - 1164 Horrible Queries 线段树+懒惰标记

来源:互联网 发布:东莞协创数据怎么样 编辑:程序博客网 时间:2024/05/10 00:31

Description

World is getting more evil and it's getting tougher to get into the Evil League of Evil. Since the legendary Bad Horse has retired, now you have to correctly answer the evil questions of Dr. Horrible, who has a PhD in horribleness (but not in Computer Science). You are given an array of n elements, which are initially all 0. After that you will be given q commands. They are -

1.      0 x y v - you have to add v to all numbers in the range of x to y (inclusive), where x and y are two indexes of the array.

2.      1 x y - output a line containing a single integer which is the sum of all the array elements between xand y (inclusive).

The array is indexed from 0 to n - 1.

Input

Input starts with an integer T (≤ 5), denoting the number of test cases.

Each case contains two integers n (1 ≤ n ≤ 105) and q (1 ≤ q ≤ 50000). Each of the next q lines contains a task in one of the following form:

0 x y v (0 ≤ x ≤ y < n, 1 ≤ v ≤ 1000)

1 x y (0 ≤ x ≤ y < n)

Output

For each case, print the case number first. Then for each query '1 x y', print the sum of all the array elements between x and y.

Sample Input

2

10 5

0 0 9 10

1 1 6

0 3 7 2

0 4 5 1

1 5 5

20 3

0 10 12 1

1 11 12

1 19 19

Sample Output

Case 1:

60

13

Case 2:

2

0


本题意思是给你n个数,然后有p个操作。如果输入0,代表是把从i到j中的元素全部加上值Value(自己定义的)。反之,当输入是1的时候,则输出从i到j之间元素的和。

由于操作p给的范围与元素的个数n都比较大,所以说那个记录和的类型应该是long  long类型的。。从WA开始,就一直在试,如果说全部元素的类型都换为long  long 肯定没错,但是没必要换的元素类型并没有换。

#include <iostream>#include <cstdio>#include <string>#include <cmath>#include <algorithm>#include <cstring>#include <map>#include <queue>#include <stack>#define INF 0x3f3f3f3f#define mem(a,b) memset(a,b,sizeof(a));#define For(a,b) for(int i = a;i<b;i++)#define LL long long#define MAX_N 100010using namespace std;struct SegmentTree{    int l;    int r;    LL sum;    int flag;}p[MAX_N<<2];void BuildTree(int root,int l,int r){    p[root].l = l;    p[root].r = r;    p[root].flag = 0;    if(l == r)    {        p[root].sum = 0;        return ;    }    int mid = (l + r)>>1;    BuildTree(root<<1,l,mid);    BuildTree(root<<1|1,mid+1,r);    p[root].sum = p[root<<1].sum + p[root<<1|1].sum;}void PushDown(int now,int l,int r){    int mid = (l+r)/2;    if(p[now].flag)    {        p[now<<1].sum += (mid-l + 1)*p[now].flag;        p[now<<1|1].sum += (r-mid)*p[now].flag;        p[now<<1].flag += p[now].flag;        p[now<<1|1].flag += p[now].flag;        p[now].flag = 0;    }    return ;}void Update(int root,int l,int r,int v){    if(l <= p[root].l && p[root].r <= r)    {        p[root].flag += v;        p[root].sum += (p[root].r - p[root].l + 1)*v;        return ;    }    PushDown(root,p[root].l,p[root].r);    int mid = (p[root].l+p[root].r)/2;    if(l>mid)        Update(root<<1|1,l,r,v);    else if(r<=mid)        Update(root<<1,l,r,v);    else    {        Update(root<<1|1,l,r,v);        Update(root<<1,l,r,v);    }    p[root].sum = p[root<<1].sum + p[root<<1|1].sum;}LL Query(int root,int l,int r){    if(l <= p[root].l && p[root].r <= r)    {        return p[root].sum;    }    PushDown(root,p[root].l,p[root].r);    int mid = (p[root].l + p[root].r)/2;    if(l>mid)        return Query(root<<1|1,l,r);    else if(r<=mid)        return Query(root<<1,l,r);    else    {        LL ans = Query(root<<1|1,l,r);        LL ans1 = Query(root<<1,l,r);        return ans + ans1;    }}int main(){    int T;    while(~scanf("%d",&T))    {        for(int w = 1; w<=T; w++)        {            int n,q,o_z,x,y,val;            scanf("%d %d",&n,&q);            BuildTree(1,1,n);            printf("Case %d:\n",w);            while(q--)            {                scanf("%d",&o_z);                if(o_z)                {                    scanf("%d %d",&x,&y);                    printf("%lld\n",Query(1,x+1,y+1));                }                else                {                    scanf("%d %d %d",&x,&y,&val);                    Update(1,x+1,y+1,val);                }            }        }    }    return 0;}


0 0
原创粉丝点击