POJ3468 A Simple Problem with Integers

本文详细介绍了一种基于线段树的数据结构实现方法,并重点介绍了懒惰操作的应用场景及其实现方式。通过具体的代码示例,展示了如何使用线段树进行区间查询与更新操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简单的线段树应用


关键词

线段树、懒操作

#include <iostream>
#include <cstdlib>
#include <cstdio>
#define maxn 100000 + 10

using namespace std;

struct node
{
    int l , r ;
    long long val , lz;
} nd[maxn<<2] ;

void buildTree( int l , int r , int rt )
{
    nd[ rt ].l = l ;
    nd[ rt ].r = r ;
    nd[ rt ].lz = 0 ;

    if( l == r )
    {
        cin >> nd[rt].val ;
        return ;
    }
    int mid = ( nd[ rt ].l + nd[ rt ].r )>>1 ;
    int ls = rt<<1 ;
    int rs = ls + 1 ;
    buildTree( l , mid , ls ) ;
    buildTree( mid + 1 , r , rs ) ;
    nd[ rt ].val = (nd[ ls ].val) + (nd[ rs ].val);
}

long long  query( int l , int r , int rt )
{
    if( nd[ rt ].l == l && nd[ rt ].r == r )
    {
        return nd[ rt ].val;
    }
    int ls = rt<<1 ;
    int rs = ls + 1 ;
    int mid = ( nd[ rt ].l + nd[ rt ].r )>>1 ;
    if( nd[ rt ].lz != 0 )
    {
        nd[ ls ].lz += nd[ rt ].lz ;
        nd[ ls ].val += ( mid - nd[ rt ].l  + 1 ) * nd[ rt ].lz ;
        nd[ rs ].lz += nd[ rt ].lz ;
        nd[ rs ].val += ( nd[ rt ].r - mid ) * nd[ rt ].lz ;
        nd[ rt ].lz = 0 ;
    }

    long long  ans ;
    if( r <= mid )  ans = query( l , r , ls );
    else if( l >= mid + 1 ) ans = query( l , r , rs );
    else  ans = query( l , mid , ls ) + query( mid + 1 , r , rs );
    return ans ;
}
void modify( int l , int r , int  x , int rt )
{
    if( nd[ rt ].l == l && nd[ rt ].r == r )
    {
        nd[ rt ].lz += x ;
        nd[ rt ].val += ( r - l + 1 ) * x ;
        return ;
    }
    int mid = ( nd[ rt ].l + nd[ rt ].r )>>1 ;
    int ls = rt<<1 ;
    int rs = ls + 1 ;
    if( nd[ rt ].lz != 0 )
    {
        nd[ ls ].lz += nd[ rt ].lz ;
        nd[ ls ].val += ( mid - nd[ rt ].l  + 1 ) * nd[ rt ].lz ;
        nd[ rs ].lz += nd[ rt ].lz ;
        nd[ rs ].val += ( nd[ rt ].r - mid ) * nd[ rt ].lz ;
        nd[ rt ].lz = 0 ;
    }

    if( r <= mid) modify( l , r , x , ls );
    else if ( l >= mid +1 ) modify( l , r , x , rs );
    else
    {
        modify( l , mid , x , ls );
        modify( mid + 1 , r , x , rs );
    }
    nd[ rt ].val = nd[ ls ].val + nd[ rs ].val ;
}
int main()
{
    //freopen("in.txt","r",stdin);
    int n , q ;
    cin >> n >> q;
    buildTree( 1 , n , 1 );
    for( int i = 1 ; i <= q ; i ++ )
    {
        char op[2];
        cin >> op ;
        if(op[ 0 ] == 'Q')
        {
            int a , b ;
            cin >> a >> b ;
            cout<< query( a , b , 1) << endl ;
        }
        else
        {
            int a , b , c ;
            cin >> a >> b >> c ;
            modify( a , b , c , 1);
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值