ACM学习历程——POJ3468 A Simple Problem with Integers(线段树)

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.

这是对区间所有点增固定值类的线段树。

代码:

#include <iostream>
#include <cstdio>
#define LL long long

using namespace std;

int n, q;

//线段树
const int maxn = 100000;
struct node
{
    int lt, rt;
    LL val, add;
}tree[4*maxn];

//建立线段树
void Build(int lt, int rt, int id)
{
    tree[id].lt = lt;
    tree[id].rt = rt;
    tree[id].val = 0;//每段的初值,根据题目要求
    tree[id].add = 0;
    if (lt == rt)
    {
        scanf("%I64d", &tree[id].val);
        //tree[id].add = ??;
        return;
    }
    int mid = (lt + rt) >> 1;
    Build(lt, mid, id << 1);
    Build(mid + 1, rt, id << 1 | 1);
    tree[id].val = tree[id<<1].val + tree[id<<1|1].val;
}

void PushDown(int id, int pls)
{
    tree[id<<1].add += tree[id].add;
    //tree[id<<1].val += (pls-(pls>>1))*tree[id].add;
    tree[id<<1].val += (tree[id<<1].rt-tree[id<<1].lt+1)*tree[id].add;
    tree[id<<1|1].add += tree[id].add;
    //tree[id<<1|1].val += (pls>>1)*tree[id].add;
    tree[id<<1|1].val += (tree[id<<1|1].rt-tree[id<<1|1].lt+1)*tree[id].add;
    tree[id].add = 0;
}

//增加区间内每个点固定的值
void Add(int lt, int rt, int id, int pls)
{
    if (lt <= tree[id].lt && rt >= tree[id].rt)
    {
        tree[id].add += pls;
        tree[id].val += pls * (tree[id].rt-tree[id].lt+1);
        return;
    }
    if (tree[id].add != 0)
    {
        PushDown(id, tree[id].rt-tree[id].lt+1);
    }
    int mid = (tree[id].lt + tree[id].rt) >> 1;
    if (lt <= mid)
        Add(lt, rt, id<<1, pls);
    if (rt > mid)
        Add(lt, rt, id<<1|1, pls);
   tree[id].val = tree[id<<1].val + tree[id<<1|1].val;
}

LL Query(int lt, int rt, int id)
{
    if (lt <= tree[id].lt && rt >= tree[id].rt)
        return tree[id].val;
    if (tree[id].add != 0)
    {
        PushDown(id, tree[id].rt-tree[id].lt+1);
    }
    int mid = (tree[id].lt + tree[id].rt) >> 1;
    LL ans = 0;
    if (lt <= mid)
        ans += Query(lt, rt, id<<1);
    if (rt > mid)
        ans += Query(lt, rt, id<<1|1);
    return ans;

}

int main()
{
    //freopen("in.txt", "r", stdin);
    char op;
    int a, b, k;
    while (scanf("%d%d", &n, &q) != EOF)
    {
        Build(1, n, 1);
        for (int i = 0; i < q; ++i)
        {
            getchar();
            op = getchar();
            getchar();
            scanf("%d%d", &a, &b);
            if (op == ‘Q‘)
                printf("%I64d\n", Query(a, b, 1));
            else
            {
                scanf("%d", &k);
                Add(a, b, 1, k);
            }
        }
    }
    return 0;
}
时间: 2024-10-12 13:56:37

ACM学习历程——POJ3468 A Simple Problem with Integers(线段树)的相关文章

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

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 97722   Accepted: 30543 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

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

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 94899   Accepted: 29568 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

poj3468 A Simple Problem with Integers(线段树模板 功能:区间增减,区间求和)

转载请注明出处:http://blog.csdn.net/u012860063 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 th

poj3468(A Simple Problem with Integers)线段树+树状数组

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. In

POJ 3468 A Simple Problem with Integers(线段树区间更新)

题目地址:POJ 3468 打了个篮球回来果然神经有点冲动..无脑的狂交了8次WA..居然是更新的时候把r-l写成了l-r... 这题就是区间更新裸题.区间更新就是加一个lazy标记,延迟标记,只有向下查询的时候才将lazy标记向下更新.其他的均按线段树的来就行. 代码如下: #include <iostream> #include <cstdio> #include <cstring> #include <math.h> #include <stac

HDU4267 A Simple Problem with Integers 线段树/树状数组

HDU4267 A Simple Problem with Integers  线段树/树状数组 2012长春网络赛A题 Problem Description Let A1, A2, ... , AN be N elements. You need to deal with two kinds of operations. One type of operation is to add a given number to a few numbers in a given interval. T

POJ3468_A Simple Problem with Integers(线段树/成段更新)

解题报告 题意: 略 思路: 线段树成段更新,区间求和. #include <iostream> #include <cstring> #include <cstdio> #define LL long long #define int_now int l,int r,int root using namespace std; LL sum[500000],lazy[500000]; void push_up(int root,int l,int r) { sum[ro

【POJ】3468 A Simple Problem with Integers ——线段树 成段更新 懒惰标记

A Simple Problem with Integers Time Limit:5000MS   Memory Limit:131072K Case Time Limit:2000MS 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

POJ3468__A Simple Problem with Integers (线段树)

本文出自blog.csdn.net/svitter --我大C++的指针岂是尔等能够简单领悟! 题意 给N个节点,标号A1~An,然后有Q个操作,操作分为Q i j,查询i,j间的区间和.C i j k,i到j个数字,每个数字增加k,并且输出. 输入输出分析 给N,Q,然后跟操作.注意判断Q,C使用scanf("%s"). 测试数据: 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 Samp