A Simple Problem with Integers---poj3468线段树

http://poj.org/problem?id=3468

题意:有一个比较长的区间可能是100000.长度, 每个点都有一个值(值还比较大),

现在有一些操作:

C a b c, 把区间a--b内全部加上c

Q a b,求区间ab的值和。

线段树 改变整个区间的数

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

#define INF 0xfffffff
#define N 100050
#define Lson root<<1
#define Rson root<<1|1

struct SegmentTree
{
    int L, R;
    long long sum, k;
    int Mid()
    {
        return (L+R)>>1;
    }
    int len()
    {
        return R-L+1;
    }
}a[N<<2];

void BuildSegTree(int root, int L, int R)
{
    a[root].L = L; a[root].R = R; a[root].k = 0;
    if( L == R )
    {
        scanf("%lld", &a[root].sum);
        return ;
    }

    BuildSegTree(Lson, L, a[root].Mid());
    BuildSegTree(Rson, a[root].Mid()+1, R);

    a[root].sum = a[Rson].sum + a[Lson].sum;
}
void PushDown(int root)
{
    a[Lson].sum += a[root].k * a[Lson].len();
    a[Lson].k += a[root].k;
    a[Rson].sum += a[root].k * a[Rson].len();
    a[Rson].k += a[root].k;

    a[root].k = 0;
}
void Update(int root, int L, int R, int k)
{
    a[root].sum += (R - L + 1) * k;
    if(a[root].L == L && a[root].R == R)
    {
        a[root].k += k;
        return ;
    }

    PushDown(root);

    if(R <= a[root].Mid())
        Update(Lson, L, R, k);
    else if(L > a[root].Mid())
        Update(Rson, L, R, k);
    else
    {
        Update(Lson, L, a[root].Mid(), k);
        Update(Rson, a[root].Mid()+1, R, k);
    }
}
long long Query(int root, int L, int R)
{
    if(a[root].L==L && a[root].R == R)
        return a[root].sum;

    PushDown(root);

    if(R <= a[root].Mid())
        return Query(Lson, L, R);
    else if( L > a[root].Mid())
        return Query(Rson, L, R);
    else
    {
        long long Lsum = Query(Lson, L, a[root].Mid());
        long long Rsum = Query(Rson, a[root].Mid()+1, R);
        return Lsum + Rsum;
    }
}

int main()
{
    int n, m, L, R, k;
    long long ans;
    char s[10];
    while(scanf("%d %d", &n, &m) != EOF)
    {
        BuildSegTree(1, 1, n);
        for(int i=0; i<m; i++)
        {
            scanf("%s", s);
            if(s[0] == ‘Q‘)
            {
                scanf("%d %d", &L, &R);
                ans = Query(1, L, R);
                printf("%lld\n", ans);
            }
            else
            {
                scanf("%d %d %d", &L, &R, &k);
                Update(1, L, R, k);
            }
        }
    }
    return 0;
}
时间: 2024-09-13 05:36:09

A Simple Problem with Integers---poj3468线段树的相关文章

POJ3468 A Simple Problem with Integers 【线段树】+【成段更新】

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

poj3468A Simple Problem with Integers(线段树的区域更新)

http://poj.org/problem?id=3468 真心觉得这题坑死我了,一直错,怎么改也没戏,最后tjj把q[rt].lz改成了long long 就对了,真心坑啊. 线段树的区域更新. 线段树功能:update:成段增减 query:区间求和 #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> using namespace std; #d

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

题目链接:http://poj.org/problem?id=3468 A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 56005   Accepted: 16903 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with

PKU A Simple Problem with Integers (线段树区间更新求和)

题意:典型的线段树C,Q问题,有n个数a[i] (1~n),C, a, b,c在[a,b]区间增加c Q a b 求[a,b]的和. #include<cstdio> #include<stdlib.h> #include<string.h> #include<string> #include<map> #include<cmath> #include<iostream> #include <queue> #i

poj 3468:A Simple Problem with Integers(线段树,区间修改求和)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 58269   Accepted: 17753 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: 62228   Accepted: 19058 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 (线段树 成段更新 加值 求和)

题目链接 题意: 只有这两种操作 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. 分析:自己写的有点麻烦了,写的时候手残+脑残,改了好久. val+lazy*(r-l+1)表示和,如果lazy==0表示当前区间加的值不统一. 1 #include <iostream

poj3511--A Simple Problem with Integers(线段树求和)

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 60441   Accepted: 18421 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(线段树 区间更新)

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