POJ3468(线段树区间维护)

#include<cstdio>
#define lson n<<1,l,mid
#define rson (n<<1)|1,mid+1,r
#define gmid (a[n].l+a[n].r)>>1
using namespace std;
const int MAX_N=100005;
typedef long long LL;
struct node{
    int l,r;
    LL sum,lazy;
}a[MAX_N<<2];
void PushUp(int n)
{
    a[n].sum=a[n<<1].sum+a[(n<<1)|1].sum;
}
void PushDown(int n)
{
    int mid =gmid;
    a[n<<1].sum+=a[n].lazy*(LL)(mid-a[n].l+1);
    a[(n<<1)|1].sum+=a[n].lazy*(LL)(a[n].r-mid);
    a[n<<1].lazy+=a[n].lazy;
    a[(n<<1)|1].lazy+=a[n].lazy;
    a[n].lazy=0;
}
void Build(int n,int l,int r)
{
    a[n].l=l;
    a[n].r=r;
    if(l==r)
    {
        scanf("%lld",&a[n].sum);
        a[n].lazy=0;
        return ;
    }
    int mid=gmid;
    Build(lson);
    Build(rson);
    PushUp(n);
}

void Update(int n,int l,int r,int val)
{
    if(a[n].l==l&&a[n].r==r)
    {
        a[n].lazy+=val;
        a[n].sum+=val*(LL)(r-l+1);
        return ;
    }
    int mid=gmid;
    if(a[n].lazy)    PushDown(n);
    if(r<=mid)    Update(n<<1,l,r,val);
    else if(mid<l) Update((n<<1)|1,l,r,val);
    else{
        Update(lson,val);
        Update(rson,val);
    }
    PushUp(n);
}

LL Query(int n,int l,int r)
{
    if(a[n].l==l&&a[n].r==r)
    {
        return a[n].sum;
    }
    int mid=gmid;
    if(a[n].lazy) PushDown(n);
    if(r<=mid)    return Query(n<<1,l,r);
    else if(mid<l) return Query((n<<1)|1,l,r);
    else return Query(lson)+Query(rson);
}
int main()
{

    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        Build(1,1,n);
        while(m--)
        {

            scanf("%*c");
            char op;
            scanf("%c",&op);
            if(op==‘Q‘)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                printf("%lld\n",Query(1,x,y));
            }
            else
            {
                int x,y,v;
                scanf("%d%d%d",&x,&y,&v);
                Update(1,x,y,v);
            }
        }
    }
    return 0;
}
时间: 2024-08-22 07:23:11

POJ3468(线段树区间维护)的相关文章

线段树 --- (区间维护+逆推)

Buy Tickets Time Limit:4000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Description Railway tickets were difficult to buy around the Lunar New Year in China, so we must get up early and join a long queue- The Lunar New Year was appro

hdu 1556 Color the ball(线段树区间维护+单点求值)

传送门:Color the ball Color the ball Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 25511    Accepted Submission(s): 12393 Problem Description N个气球排成一排,从左到右依次编号为1,2,3....N.每次给定2个整数a b(a <= b),lele

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-3468(线段树+区间更新+区间查询)

A Simple Problem With Integers POJ-3468 这题是区间更新的模板题,也只是区间更新和区间查询和的简单使用. 代码中需要注意的点我都已经标注出来了,容易搞混的就是update函数里面还需要计算sum数组.因为这里查询的时候是直接用sum查询结点. //区间更新,区间查询 #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #inc

Codevs-4919 线段树练习4(区间加上一个值并求摸个区间整除k的数的个数,线段树+数组维护)

给你N个数,有两种操作 1:给区间[a,b]内的所有数都增加X 2:询问区间[a,b]能被7整除的个数 输入描述 Input Description 第一行一个正整数n,接下来n行n个整数,再接下来一个正整数Q,表示操作的个数. 接下来Q行每行若干个整数.如果第一个数是add,后接3个正整数a,b,X,表示在区间[a,b]内每个数增加X,如果是count,表示统计区间[a,b]能被7整除的个数 输出描述 Output Description 对于每个询问输出一行一个答案 样例输入 Sample

P2023 [AHOI2009]维护序列 (线段树区间修改查询)

题目链接:https://www.luogu.org/problemnew/show/P2023 一道裸的线段树区间修改题,懒惰数组注意要先乘后加 #include<bits/stdc++.h> using namespace std; typedef long long LL; const int maxx = 400010; LL tree[maxx],lazy1[maxx],lazy2[maxx],a[maxx],mod; int n; void build(int l,int r,in

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

http://poj.org/problem?id=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 number to each number in a given interval. The other is to ask for the sum of

poj3468 线段树 or splay

poj3468  裸线段树.因为在熟悉splay 所以就用splay交了一发...开始用的scanf()!==2 居然TLE了...然后我就当单组测试数据做的 然后就过了  囧TZ #include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <cmath> using namespac

POJ 3667 线段树区间合并

http://www.cnblogs.com/scau20110726/archive/2013/05/07/3065418.html 用线段树,首先要定义好线段树的节点信息,一般看到一个问题,很难很快能确定线段树要记录的信息做线段树不能为了做题而做,首先线段树是一种辅助结构,它是为问题而生的,因而必须具体问题具体分析回忆一下RMQ问题,其实解决RMQ有很多方法,根本不需要用到线段树,用线段树解决RMQ,其实是利用线段树的性质来辅助解决这个问题回忆一下求矩形面积并或周长并的问题,一般使用的是扫描