A Simple Problem with Integers-POJ3468 区间修改+区间查询

题意:

给你n个数和2个操作,C操作是将一个区间内的每个数都加上k,Q操作是询问一个区间的和

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

思路:

线段树区间修改+区间查询

代码:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include <math.h>
using namespace std;
const int MAXN=2e5+5;
typedef long long ll;
ll tree[MAXN<<2];
ll lazy[MAXN<<2];    //lazy数组为区间修改时引进的一个标记数组
void push_up(ll node)
{
    tree[node]=tree[node<<1]+tree[node<<1|1];
}
void build(ll node,ll l, ll r)
{
    if(l==r)
    {
        scanf("%lld",&tree[node]);
        return ;
    }
    ll mid=(l+r)>>1;
    build(node<<1,l,mid);
    build(node<<1|1,mid+1,r);
    push_up(node);
}

/*
push_down函数用来下传lazy标记,左右儿子的lazy等于父亲节点的lazy,
左儿子的区间和改变的数值为左儿子的区间长度*lazy[node]的值,右儿子同理,
下传结束后将父亲节点的lazy[node]变为0.
*/

void push_down(int node,int l,int r,int mid)    
{

        lazy[node<<1]+=lazy[node];
        lazy[node<<1|1]+=lazy[node];
        tree[node<<1]+=(mid-l+1)*lazy[node];
        tree[node<<1|1]+=(r-mid)*lazy[node];
        lazy[node]=0;

}
void update(int node,int l,int r,int x,int y,int k)    //区间修改函数
{
    if(x<=l&&y>=r)   //如果l,r在范围内,该区间的和直接增加(r-l+1)*k,打上lazy标记
    {
        tree[node]+=(r-l+1)*k;
        lazy[node]+=k;
        return;
    }
    ll mid=(l+r)>>1;
    if(lazy[node])    //如果有lazy标记,则下传
        push_down(node,l,r,mid);
    if(x<=mid)
        update(node<<1,l,mid,x,y,k);
    if(y>mid)
        update(node<<1|1,mid+1,r,x,y,k);
    push_up(node);    //修改他父亲区间的和
}
ll query(ll node,ll l,ll r,ll x,ll y)
{
    if(x<=l&&y>=r)
        return tree[node];
    ll mid=(l+r)>>1;
    if(lazy[node])push_down(node,l,r,mid);
    ll ans=0;
    if(x<=mid)
        ans+=query(node<<1,l,mid,x,y);
    if(y>mid)
        ans+=query(node<<1|1,mid+1,r,x,y);
    return ans;
}
int main()
{
    ll n,q;scanf("%lld%lld",&n,&q);
    build(1,1,n);
    for(int i=1;i<=q;i++)
    {
        char str[3];
        scanf("%s",str);
        ll x,y;
        if(str[0]=='Q')
        {
            scanf("%lld%lld",&x,&y);
            printf("%lld\n",query(1,1,n,x,y));
        }
        else
        {
            ll k;
            scanf("%lld%lld%lld",&x,&y,&k);
            update(1,1,n,x,y,k);
        }
    }
    return 0;
}
posted @ 2020-01-21 19:13  grass_lin  阅读(109)  评论(0编辑  收藏  举报