poj 4047 Garden(线段树)

本文介绍了一种利用线段树解决区间连续k个值和的最大值问题的方法,并提供了完整的代码实现。该方法支持单点更改和元素交换操作,适用于POJ 4047题目。

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

求给定区间连续k个值和的最大值,有单点更改和交换操作。

这题主要是建树,以每个节点开始的连续k个值的和作为一个节点,这样共有n-k+1个节点,更新时计算出更新的点所在节点的范围,更新值为 新值-旧值。

交换即为两次更新,线段树记录节点最大值。

code:

#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include < string>
#include <iostream>
#include <sstream>
#include < set>
#include <queue>
#include <stack>
#include <fstream>
#include <iomanip>
#include <bitset>
#include <list>
#include <ctime>
using  namespace std ;

#define SET(arr, what)  memset(arr, what, sizeof(arr))
#define FF(i, a)        for(i=0; i<a; i++)
#define SD(a)           scanf("%d", &a)
#define SSD(a, b)       scanf("%d%d", &a, &b)
#define SSF(a, b)       scanf("%lf%lf", &a, &b)
#define SS(a)           scanf("%s", a)
#define SLD(a)          scanf("%lld", &a)
#define PF(a)           printf("%d\n", a)
#define PPF(a, b)       printf("%d %d\n", a, b)
#define PLF(a)          printf("%lf\n", a)
#define SZ(arr)         (int)a.size()
#define SWAP(a,b)       a=a xor b;b= a xor b;a=a xor b;
#define read            freopen("in.txt", "r", stdin)
#define write            freopen("out.txt", "w", stdout)
#define MAX             1<<30
#define ESP             1e-5
#define lson            l, m, rt<<1
#define rson            m+1, r, rt<<1|1
template< class T> inline T sqr(T a){ return a*a;}
template< class T> inline  void AMin(T &a,T b){ if(a==- 1||a>b)a=b;}
template< class T> inline  void AMax(T &a,T b){ if(a<b)a=b;}
template< class T> inline T Min(T a,T b){ return a>b?b:a;}
template< class T> inline T Max(T a,T b){ return a>b?a:b;}
const  int maxn =  222222 ;
int data[maxn], q[maxn], sum[maxn<< 2], cover[maxn<< 2] ;
void pushup( int rt){
    sum[rt] = Max(sum[rt<< 1], sum[rt<< 1| 1]) ;
}
void pushdown( int rt){
     if(cover[rt]!= 0){
        cover[rt<< 1] += cover[rt] ;
        cover[rt<< 1| 1] += cover[rt] ;
        sum[rt<< 1] += cover[rt] ;
        sum[rt<< 1| 1] += cover[rt] ;
        cover[rt] =  0 ;
    }
}
void build( int l,  int r,  int rt){
    cover[rt] =  0 ;
     if(l==r){
        sum[rt] = q[l] ;
         return ;
    }
     int m = (l + r) >>  1 ;
    build(lson) ;
    build(rson) ;
    pushup(rt) ;
}
void update( int L,  int R,  int val,  int l,  int r,  int rt){
     if(L<=l&&r<=R){
        cover[rt] += val ;
        sum[rt] += val ;
         return ;
    }
    pushdown(rt) ;
     int m = (l + r) >>  1 ;
     if(L<=m)    update(L, R, val, lson) ;
     if(R>m)     update(L, R, val, rson) ;
    pushup(rt) ;
}
int query( int L,  int R,  int l,  int r,  int rt){
     if(L<=l&&r<=R){
         return sum[rt] ;
    }
    pushdown(rt) ;
     int m = (l + r) >>  1 ;
     int ret = -MAX ;
     if(L<=m)    ret = Max(ret, query(L, R, lson)) ;
     if(m<R)     ret = Max(ret, query(L, R, rson)) ;
     return ret ;
}
int main(){
     int t, n, k, m, temp, i, j, cnt ;
    SD(t) ;
     while(t--){
        cnt =  1, temp =  0 ;
        SD(n) ;SSD(m, k) ;
         for(i= 1; i<=n; i++){
            SD(data[i]) ;
            temp += data[i] ;
             if(i>k){
                temp -= data[i-k] ;
                q[++cnt] = temp ;
            } else   q[cnt] = temp ;
        }
        build( 1, cnt,  1) ;
         while(m--){
             int a, b ;
            SD(temp) ;SSD(a, b) ;
             if(temp== 2){
                PF(query(a, b+ 1-k,  1, cnt,  1)) ;
            }
             if(temp== 1){
                 if(a==b)     continue ;
                 if(a>b){
                     int c = a ;a = b ;b = c ;
                }
                 int v = data[b] - data[a] ;
                 int x = Max( 1, a-k+ 1) ;
                 int y = Min(a, cnt) ;
                update(x, y, v,  1, cnt,  1) ;
                v = data[a] - data[b] ;
                x = Max( 1, b-k+ 1) ;
                y = Min(b, cnt) ;
                update(x, y, v,  1, cnt,  1) ;
                v = data[a], data[a] = data[b], data[b] = v ;
            }
             if(temp== 0){
                 int v = b - data[a] ;
                data[a] = b ;
                 int x = Max( 1, a-k+ 1) ;
                 int y = Min(a, cnt) ;
                update(x, y, v,  1, cnt,  1) ;
            }
        }
    }
     return  0 ;
}

转载于:https://www.cnblogs.com/xiaolongchase/archive/2012/08/22/2650200.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值