zoukankan      html  css  js  c++  java
  • poj 4047 Garden(线段树)

    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 ;
    }

  • 相关阅读:
    TopCoder<SRM>上的一道1100分的题目解析附代码
    《算法导论》思考题15-2 整齐打印
    《算法导论》思考题15-1 双调欧几里得旅行商问题(动态规划)
    <ReversingEngineering>关于windows32位系统下的dll注入技术经验汇
    实现一个EventEmitter类,这个类包含以下方法: on/ once/fire/off
    [Jquery 插件]活动倒计时,可同步服务器时间,倒计时格式随意设置
    阻止a标签跳转四种方法 兼容各大浏览器(包括IE)
    git常用操作 配置用户信息、拉取项目、提交代码、分支操作、版本回退...
    nrm npm源管理利器
    Element UI 框架搭建
  • 原文地址:https://www.cnblogs.com/xiaolongchase/p/2650200.html
Copyright © 2011-2022 走看看