zoukankan      html  css  js  c++  java
  • poj 2750 Potted Flower (线段树)

    http://poj.org/problem?id=2750
    
    /*
    问题描述:给定一个环形序列,进行在线操作,每次修改一个元素,输出环上的最大连续子列的和,但不能是完全序列。
    算法:把环从一个地方,切断拉成一条直线,用线段树记录当前区间的非空最大子列和当前区间的非空最小子列。
    动态规划解决过静态的序列最大连续子序列和问题,时间复杂度可以达到 n(环形序列可能复杂度更高)。但是这里涉及到动态更新,更新频度很大,如果计算子序列和复杂度仍然是n,就会非常耗时。
    如果环上的数都是正整数,答案是:环上数的总和-根结点的非空最小子列;否则,答案是:max{根结点的非空最大子列, 环上数的总和-根结点的非空最小子列}
    
    
    一开始想到,如果将环从一点断开,那么最大和如果包括断点的最后一个点和第一个点,那该如何求
    ,仔细看了一下 ,终于向明白了,如果 段的最大自序列包括 断点 那么断点一定是正数;
      那么   环上数的总和-根结点的非空最小子列,就将断点包括了。
    
    
    
    */
    
    #include<stdio.h>
    #include<iostream>
    #define N 100050
    using namespace std;
    int n,m;
    int a[N];
    struct node
    {
        int l,r,sum;
        int xmax,xmin;
        int lmax,lmin;
        int rmax,rmin;
    }p[N*3];
    void update(int x)
    {
        p[x].sum=p[x*2].sum+p[x*2+1].sum;
    
           p[x].lmax=max(p[x*2].lmax,p[x*2].sum+p[x*2+1].lmax);
           p[x].rmax=max(p[x*2+1].rmax,p[x*2].rmax+p[x*2+1].sum);//跨区间求最值
           p[x].xmax=max(max(p[x*2].xmax,p[x*2+1].xmax),p[x*2].rmax+p[x*2+1].lmax);
    
         p[x].lmin=min(p[x*2].lmin,p[x*2].sum+p[x*2+1].lmin);
         p[x].rmin=min(p[x*2+1].rmin,p[x*2].rmin+p[x*2+1].sum);
         p[x].xmin=min(min(p[x*2].xmin,p[x*2+1].xmin),p[x*2].rmin+p[x*2+1].lmin);
    
    
    }
    void build(int x,int l,int r)
    {
        p[x].l=l;
        p[x].r=r;
        if(l==r)
        {
            p[x].sum=p[x].xmax=p[x].xmin=a[l];
            p[x].lmax=p[x].lmin=a[l];
            p[x].rmax=p[x].rmin=a[l];
            return ;
        }
        int mid=(l+r)/2;
        build(x*2,l,mid);
        build(x*2+1,mid+1,r);
    
        update(x);
    
    }
    void change(int x,int pos,int y)
    {
    
        if(p[x].l==p[x].r&&p[x].l==pos)
        {
            p[x].sum=p[x].xmax=p[x].xmin=y;
            p[x].lmax=p[x].lmin=y;
            p[x].rmax=p[x].rmin=y;
            return ;
        }
    
        int mid=(p[x].l+p[x].r)/2;
        if(pos<=mid)change(x*2,pos,y);
        else  change(x*2+1,pos,y);
    
        update(x);
    
    }
    int main()
    {
        scanf("%d",&n);
    
            for(int i=1;i<=n;i++)scanf("%d",&a[i]);
            build(1,1,n);
            scanf("%d",&m);
            int pos,y;
            while(m--)
            {
                scanf("%d%d",&pos,&y);
                change(1,pos,y);
                //printf("%d %d %d\n",p[1].sum,p[1].xmax,p[1].xmin);
                if(p[1].sum==p[1].xmax)
                {
                    printf("%d\n",p[1].sum-p[1].xmin);
                }
                else
                {
                    printf("%d\n",max(p[1].xmax,p[1].sum-p[1].xmin));
                }
            }
    
    
    }
    

      

  • 相关阅读:
    ExtJs 4 的filefield上传后 返回值success接受不正常
    winform treeview 通过节点名称添加子节点
    Live Writer Test
    mysqlcluster笔记
    ExtJS中form提交之后获取返回的json值
    MYSQL大小写(由于数据由windows迁移到Linux导致)
    ORACLE分科目统计每科前三名的学生的语句
    一列数据横排显示
    Oracle11g使用exp导出空表
    myeclipse2015卸载、安装、破解全过程-----myeclipse2015
  • 原文地址:https://www.cnblogs.com/acSzz/p/2457897.html
Copyright © 2011-2022 走看看