线段树的区间更新---A Simple Problem with Integers

POJ   3468

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

思路:线段树区间更新。

本题代码是很好的线段树区间更新模板:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define LL long long
using namespace std;
const int maxn=100005;
struct Node
{
    LL sum,val;
} node[4*maxn];

void pushup(int i)
{
    node[i].sum=node[i<<1].sum+node[i<<1|1].sum;
}

void pushdown(int i,int m)
{
    if(node[i].val)
    {
        node[i<<1].val+=node[i].val;
        node[i<<1|1].val+=node[i].val;
        node[i<<1].sum+=(LL)node[i].val*(m-(m>>1));
        node[i<<1|1].sum+=(LL)node[i].val*(m>>1);
        node[i].val=0;
    }
}

void build(int l,int r,int i)
{
    node[i].val=0;
    if(l==r)
    {
        scanf("%I64d",&node[i].sum);
        return ;
    }
    int mid=(l+r)/2;
    build(l,mid,i<<1);
    build(mid+1,r,i<<1|1);
    pushup(i);
}

LL query(int L,int R,int l,int r,int i)
{
   if(L<=l&&r<=R)
    {
        return node[i].sum;
    }
    int mid=(l+r)>>1;
    pushdown(i,r-l+1);
    LL ans=0;
    if(L<=mid)ans+=query(L,R,l,mid,i<<1);
    if(mid<R)ans+=query(L,R,mid+1,r,i<<1|1);
    pushup(i);
    return ans;
}

void update(int L,int R,int add,int l,int r,int i)
{
     if(L<=l&&r<=R)
    {
        node[i].sum+=(LL)add*(r-l+1);
        node[i].val+=add;
        return ;
    }
    pushdown(i,r-l+1);
    int mid=(l+r)>>1;
    if(L<=mid)update(L,R,add,l,mid,i<<1);
    if(mid<R)update(L,R,add,mid+1,r,i<<1|1);
    pushup(i);
}

int main()
{
    int n,q,a,b;
    LL c;
    while(scanf("%d%d",&n,&q)!=EOF)
    {
        build(1,n,1);
        char s[3];
        while(q--)
        {
            scanf("%s",s);
            if(s[0]==‘C‘)
            {
                scanf("%d%d%I64d",&a,&b,&c);
                update(a,b,c,1,n,1);
            }
            else if(s[0]==‘Q‘)
            {
                scanf("%d%d",&a,&b);
                printf("%I64d\n",query(a,b,1,n,1));
            }
        }
    }
    return 0;
}
时间: 2024-10-05 04:45:01

线段树的区间更新---A Simple Problem with Integers的相关文章

POJ3468——线段树区间更新——A Simple Problem with Integers

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 firs

POJ A Simple Problem with Integers 【线段树,区间更新】

题意:你有N个整数,A1,A2,-,一个.你需要处理两种类型的操作.一种类型的操作是添加了一些给定的数字,每个数字在一个给定的时间间隔.另一种是在给定的时间间隔要求数量的总和. 难点:主要是lazy标记,不好弄懂, 其实lazy标记就是当前改变的值不全部更新,等到用的时候再更新,这样就节省了好多时间. 题目链接:http://poj.org/problem?id=3468 代码: #include<stdio.h> #include<string.h> #define MAXN 1

FZU Problem 2171 防守阵地 II (线段树,区间更新)

 Problem 2171 防守阵地 II Accept: 143    Submit: 565Time Limit: 3000 mSec    Memory Limit : 32768 KB  Problem Description 部队中总共有N个士兵,每个士兵有各自的能力指数Xi,在一次演练中,指挥部确定了M个需要防守的地点,指挥部将选择M个士兵依次进入指定地点进行防守任务,获得的参考指数即为M个士兵的能力之和.随着时间的推移,指挥部将下达Q个指令来替换M个进行防守的士兵们,每个参加完防守

poj 2777 线段树的区间更新

Count Color Time Limit: 1000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Java class name: Main [Submit] [Status] [Discuss] Description Chosen Problem Solving and Program design as an optional course, you are required to solve al

HDU 4902 线段树(区间更新)

Nice boat Time Limit: 30000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 353    Accepted Submission(s): 169 Problem Description There is an old country and the king fell in love with a devil. The devil alw

CodeForces 52C Circular RMQ(区间循环线段树,区间更新,区间求和)

转载请注明出处:http://blog.csdn.net/u012860063 题目链接:http://codeforces.com/problemset/problem/52/C You are given circular array a0,?a1,?...,?an?-?1. There are two types of operations with it: inc(lf,?rg,?v) - this operation increases each element on the segm

hdu 1556:Color the ball(线段树,区间更新,经典题)

Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7941    Accepted Submission(s): 4070 Problem Description N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的"小飞鸽"牌电

hdu 1698:Just a Hook(线段树,区间更新)

Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 15129    Accepted Submission(s): 7506 Problem Description In the game of DotA, Pudge's meat hook is actually the most horrible thing f

java-HDU1698(线段树的区间更新,和区间查询)

HDU1698: 题目意思: Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 49065    Accepted Submission(s): 23200 Problem Description In the game of DotA, Pudge’s meat hook is actually the most