zoukankan      html  css  js  c++  java
  • POJ 2750 Potted Flower(线段树的区间合并)

    点我看题目链接

    题意 : 很多花盆组成的圆圈,每个花盆都有一个值,给你两个数a,b代表a位置原来的数换成b,然后让你从圈里找出连续的各花盆之和,要求最大的。

    思路 :这个题比较那啥,差不多可以用DP的思想来解决这个问题,你在某个地方将这个环断开,因为线段树无法建成环形的。然后再去找那个最大值。将这个序列分成两部分,先求左边的最大连续和a,再求右边连续和b,但是由于他们中间相连的那部分,就是左部分的最右边的连续最大和x加上右部分的最左边的连续最大和y加起来可能比ab都大,但分开的话可能并没有a或b大。所以要进行区间合并,将y并到左边去,或者将x并到右边去,但本身那个边界不变

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    
    using namespace std;
    
    const int maxn = 10100000 ;
    int maxx[maxn << 2],minn[maxn << 2] ;
    int lmax[maxn << 2],rmax[maxn << 2] ;
    int lmin[maxn << 2],rmin[maxn << 2] ;
    int sum[maxn << 2] ;
    
    void dp(int v)
    {
        int l = v << 1 ,r = l+1;
        sum[v] = sum[l]+sum[r] ;
        maxx[v] = max(max(maxx[l],maxx[r]),lmax[r] + rmax[l]) ;
        minn[v] = min(min(minn[l],minn[r]),lmin[r] + rmin[l]) ;
        lmax[v] = max(lmax[l],sum[l]+lmax[r]) ;
        rmax[v] = max(rmax[r],sum[r]+rmax[l]) ;
        lmin[v] = min(lmin[l],sum[l]+lmin[r]) ;
        rmin[v] = min(rmin[r],sum[r]+rmin[l]) ;
    }
    void build(int v,int l,int r)
    {
        if(l == r)
        {
            scanf("%d",&sum[v]) ;
            maxx[v] = minn[v] = lmax[v] = rmax[v] = lmin[v] = rmin[v] = sum[v] ;
            return ;
        }
        int mid = (l+r) >> 1 ;
        build(v*2,l,mid) ;
        build(v*2+1,mid+1,r) ;
        dp(v) ;
    }
    void update(int v,int l,int r,int num,int value)
    {
        if(l == r)
        {
            sum[v] = maxx[v] = minn[v] = value ;
            lmax[v] = rmax[v] = lmin[v] = rmin[v] = value ;
            return ;
        }
        int mid = (l+r) >> 1 ;
        if(mid >= num) update(v*2,l,mid,num,value) ;
        else update(v*2+1,mid+1,r,num,value) ;
        dp(v) ;
    }
    
    
    int main()
    {
        int n ;
        while(~scanf("%d",&n))
        {
            build(1,1,n) ;
            int m ;
            scanf("%d",&m) ;
            while(m--)
            {
                int x,y ;
                int ans ;
                scanf("%d %d",&x,&y) ;
                update(1,1,n,x,y) ;
                if(sum[1] == maxx[1])
                    ans = sum[1]-minn[1] ;
                else
                    ans = max(maxx[1], sum[1]-minn[1]) ;
                printf("%d
    ",ans) ;
            }
        }
        return 0;
    }
    View Code

             

  • 相关阅读:
    二 、异常
    Java的基本概念
    Oracle case when
    oracle exists
    一 、前言
    location
    HTTP1.1初识
    数学学习笔记(持续更新中)
    [NOIP2017 提高组] 列队 题解
    [NOI2019] 回家路线 题解
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/3564738.html
Copyright © 2011-2022 走看看