poj 3468 A Simple Problem with Integers 【线段树-成段更新】

题目:poj 3468 A Simple Problem with Integers

题意:给出n个数,两种操作

1:l -- r 上的所有值加一个值val

2:求l---r 区间上的和

分析:线段树成段更新,成段求和

树中的每个点设两个变量sum 和 num ,分别保存区间 l--r 的和 和l---r 每个值要加的值

对于更新操作:对于要更新到的区间上面的区间,直接进行操作 加上 (r - l +1)* val 。下面的区间标记num += val

对于求和操作,每次进行延迟更新,把num值分别更新到两个子区间,sum值更新,然后num值变为0

注意:这个题目会超int 。所以

AC代码:

#include <iostream>
#include <algorithm>
#include <string>
#include <math.h>
#include <vector>
#include <cstring>
#include <cstdio>
using namespace std;
const long long N = 110000;
const long long inf = 0x3f3f3f3f;
struct Node
{
    long long l,r;
    long long num,sum;
};
Node tree[5*N];
long long a[N];
long long cnt ;
void build(long long o,long long l,long long r)
{
    tree[o].l = l,tree[o].r = r;
    tree[o].num = 0;
    if(l==r)
    {
        tree[o].sum = a[cnt++];
        return ;
    }
    long long mid = (l+r)/2;
    build(o+o,l,mid);
    build(o+o+1,mid+1,r);
    tree[o].sum = tree[o+o].sum + tree[o+o+1].sum;
}
void push_update(long long o)
{
    if(tree[o].num!=0)
    {
        tree[o].sum += tree[o].num * (tree[o].r-tree[o].l+1);
        tree[o+o+1].num += tree[o].num;
        tree[o+o].num += tree[o].num;
        tree[o].num = 0;
    }
}
void update(long long o,long long l,long long r,long long val)
{
    if(l==tree[o].l && r == tree[o].r)
    {
        tree[o].num += val;
        return ;
    }
    tree[o].sum += (val*(r-l+1)); //维护前面的
    long long mid = (tree[o].l+tree[o].r) / 2;
    if(r<=mid)
        update(o+o,l,r,val);
    else if(l>mid)
        update(o+o+1,l,r,val);
    else
    {
        update(o+o,l,mid,val);
        update(o+o+1,mid+1,r,val);
    }
}
long long query(long long o,long long l,long long r)
{
    if(tree[o].l==l && tree[o].r == r)
    {
        return tree[o].sum+(r-l+1)*tree[o].num;
    }
    push_update(o); //维护后面的
    long long mid = (tree[o].l+tree[o].r)/2;
    if(r<=mid)
        return query(o+o,l,r);
    else if(l>mid)
        return query(o+o+1,l,r);
    else
        return query(o+o,l,mid) + query(o+o+1,mid+1,r);
}
int main()
{
    //freopen("Input.txt","r",stdin);
    long long n,m;
    while(~scanf("%lld%lld",&n,&m))
    {
        cnt = 0;
        for(long long i=0;i<n;i++)
            scanf("%lld",&a[i]);
        build(1,1,n);
        while(m--)
        {
            getchar();
            char c;
            long long x,y;
            scanf("%c",&c);
            scanf("%lld%lld",&x,&y);
            //printf("*****************************************\n");
            if(c=='Q')
            {
                printf("%lld\n",query(1,x,y));
            }
            else
            {
                long long val;
                scanf("%lld",&val);
                update(1,x,y,val);
            }
        }
    }
    return 0;
}
时间: 2024-10-11 21:33:09

poj 3468 A Simple Problem with Integers 【线段树-成段更新】的相关文章

POJ 3468 A Simple Problem with Integers 线段树成段更新

线段树功能 update:成段更新  query:区间求和 #include <iostream> #include <string> #include <cstdio> #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 using namespace std; typedef long long ll; const int MAXN = 111111; ll sum[MAXN<&l

【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(线段树/成段更新)

解题报告 题意: 略 思路: 线段树成段更新,区间求和. #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

A Simple Problem with Integers 线段树 成段更新

Time Limit:5000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3468 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

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

poj 3468 A Simple Problem with Integers 线段树第一次 + 讲解

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

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

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 62431   Accepted: 19141 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 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

POJ 3468 A Simple Problem with Integers //线段树的成段更新

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 59046   Accepted: 17974 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 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