题目链接:http://www.spoj.com/problems/GSS5/

题意:给出一个数列。每次查询最大子段和Sum[i,j],其中i和j满足x1<=i<=y1,x2<=j<=y2,x1<=x2,y1<=y2。

思路:线段树的节点[L,R]保存LMax,RMax,Max,sum,表示左起最大值、右起最大值、区间最大值、区间数字和。更新比较简单。下面说查询。另外设置三个函数,可以查询任意区间[L,R]的最大值,以L开始向右最多到R的最大值、以R开始向左最多到L的最大值,设其分别为Q(L,R),QL(L,R),QR(L,R)。查询分两种情况讨论(设输入数组为d,S[i]表示d的前i项和):

(1)x2>y1: ans=QR(x1,y1)+S[x2-1]-S[y1]+QL(x2,y2);

(2)x2<=y1,那么有x1<=x2<=y1<=y2,则答案为下面三种情况的最大值:

a、x1<=i<=x2<=j<=y2,ans=QR(x1,x2)+QL(x2,y2)-d[x2];

b、x2<=i<=j<=y1,ans=Q(x2,y1);

c、x1<=i<=y1<=j<=y2,ans=QR(x1,y1)+QL(y1,y2)-d[y1]。

struct node
{
    int LMax,RMax,Max,sum;
    int L,R;
};

node a[N<<2];
int d[N],S[N];
int n;

void pushUp(int t)
{
    if(a[t].L==a[t].R) return;

a[t].LMax=max(a[t*2].LMax,a[t*2].sum+a[t*2+1].LMax);
    a[t].RMax=max(a[t*2+1].RMax,a[t*2+1].sum+a[t*2].RMax);
    a[t].sum=a[t*2].sum+a[t*2+1].sum;
    a[t].Max=max3(a[t*2].Max,a[t*2+1].Max,a[t*2].RMax+a[t*2+1].LMax);
}

void build(int t,int L,int R)
{
    a[t].L=L;
    a[t].R=R;
    if(L==R)
    {
        a[t].sum=d[L];
        a[t].LMax=a[t].RMax=a[t].Max=d[L];
        return;
    }
    int mid=(L+R)>>1;
    build(t*2,L,mid);
    build(t*2+1,mid+1,R);
    pushUp(t);
}

int queryL(int t,int L,int R)
{
    if(a[t].L==L&&a[t].R==R) return a[t].LMax;

int mid=(a[t].L+a[t].R)>>1;
    int ans;
    if(R<=mid) ans=queryL(t*2,L,R);
    else if(L>mid) ans=queryL(t*2+1,L,R);
    else
    {
        ans=max(queryL(t*2,L,mid),S[mid]-S[L-1]+queryL(t*2+1,mid+1,R));
    }
    return ans;
}

int queryR(int t,int L,int R)
{
    if(a[t].L==L&&a[t].R==R) return a[t].RMax;

int mid=(a[t].L+a[t].R)>>1;
    int ans;
    if(R<=mid) ans=queryR(t*2,L,R);
    else if(L>mid) ans=queryR(t*2+1,L,R);
    else
    {
        ans=max(queryR(t*2,L,mid)+S[R]-S[mid],queryR(t*2+1,mid+1,R));
    }
    return ans;
}

int query(int t,int L,int R)
{
    if(a[t].L==L&&a[t].R==R) return a[t].Max;

int mid=(a[t].L+a[t].R)>>1;
    int ans;
    if(R<=mid) ans=query(t*2,L,R);
    else if(L>mid) ans=query(t*2+1,L,R);
    else
    {
        int x=query(t*2,L,mid);
        int y=query(t*2+1,mid+1,R);
        ans=max(x,y);
        ans=max(ans,queryR(t*2,L,mid)+queryL(t*2+1,mid+1,R));
    }
    return ans;
}

int cal(int x1,int y1,int x2,int y2)
{
    int a,b,c;
    if(x2>y1)
    {
        a=queryR(1,x1,y1);
        b=queryL(1,x2,y2);
        return a+b+S[x2-1]-S[y1];
    }
    int ans;
    a=queryR(1,x1,x2);
    b=queryL(1,x2,y2);
    ans=a+b-d[x2];

a=query(1,x2,y1);
    ans=max(ans,a);

a=queryR(1,x1,y1);
    b=queryL(1,y1,y2);
    ans=max(ans,a+b-d[y1]);

return ans;
}

int main()
{
    rush()
    {
        RD(n);
        int i;
        FOR1(i,n) RD(d[i]),S[i]=S[i-1]+d[i];
        build(1,1,n);
        int x1,y1,x2,y2;
        int m;
        RD(m);
        while(m--)
        {
            RD(x1,y1); RD(x2,y2);
            PR(cal(x1,y1,x2,y2));
        }
    }
}

SPOJ 2916 Can you answer these queries V(线段树-分类讨论)的更多相关文章

  1. GSS5 spoj 2916. Can you answer these queries V 线段树

    gss5 Can you answer these queries V 给出数列a1...an,询问时给出: Query(x1,y1,x2,y2) = Max { A[i]+A[i+1]+...+A[ ...

  2. SPOJ GSS5 Can you answer these queries V ——线段树

    [题目分析] GSS1上增加区间左右端点的限制. 直接分类讨论就好了. [代码] #include <cstdio> #include <cstring> #include & ...

  3. SPOJ GSS3 Can you answer these queries III[线段树]

    SPOJ - GSS3 Can you answer these queries III Description You are given a sequence A of N (N <= 50 ...

  4. SPOJ 1557. Can you answer these queries II 线段树

    Can you answer these queries II Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 https://www.spoj.com/pr ...

  5. bzoj 2482: [Spoj GSS2] Can you answer these queries II 线段树

    2482: [Spoj1557] Can you answer these queries II Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 145 ...

  6. SPOJ GSS1 - Can you answer these queries I(线段树维护GSS)

    Can you answer these queries I SPOJ - GSS1 You are given a sequence A[1], A[2], -, A[N] . ( |A[i]| ≤ ...

  7. SPOJ GSS1 Can you answer these queries I[线段树]

    Description You are given a sequence A[1], A[2], ..., A[N] . ( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ). A q ...

  8. 【SP2916】Can you answer these queries V - 线段树

    题面 You are given a sequence \(a_1,a_2,...,a_n\). (\(|A[i]| \leq 10000 , 1 \leq N \leq 10000\)). A qu ...

  9. SPOJ GSS3 Can you answer these queries III ——线段树

    [题目分析] GSS1的基础上增加修改操作. 同理线段树即可,多写一个函数就好了. [代码] #include <cstdio> #include <cstring> #inc ...

随机推荐

  1. CSS3中box-shadow的用法介绍

    一般我们通过box-shadow来设置盒阴影,但是有些属性我们一般没有用到,这篇文章将对box-shadow属性进行逐个分析.语法 CSS Code复制内容到剪贴板 E {box-shadow:ins ...

  2. 【BZOJ】【1269】【AHOI2006】文本编辑器editor

    Splay Splay序列维护的模板题了……为了便于处理边界情况,我们可以先插入两个空格当作最左端和最右端,然后……其实本题主要考察的就是Build.splay和Findkth这三个操作,我们可以实现 ...

  3. 【转载】C++——CString用法大全

    CString常用方法简介 作者:webmaster 出处:无 CString::Compareint Compare( LPCTSTR lpsz ) const;返回值  字符串一样 返回0     ...

  4. wrap device

    刚刚看见了,wrap device && reference device 区别在这里 https://msdn.microsoft.com/en-us/library/windows ...

  5. 在linux中使用phpize安装php扩展模块

    介绍:linux系统中,php安装成功后,在bin目录下会生成一个名叫phpize的可执行脚本,这个脚本的用途是动态安装php扩展模块.使用phpize脚本安装php扩展模块的好处:在安装php时没有 ...

  6. struts2漏洞原理及解决办法

    1.原理 Struts2的核心是使用的webwork框架,处理action时通过调用底层的getter/setter方法来处理http的参数,它将每个http参数声明为一个ONGL(这里是ONGL的介 ...

  7. 十个实用但IE不支持的CSS属性

    对IE浏览器尤其是IE6的抱怨基本已进入麻痹状态,偶尔甚至产生非常消极的想法:这个世界只有一个浏览器就好了,哪怕这唯一的浏览器就是IE6.当然,这样的想法是非常病态的,马上打消.本文里面,介绍了10个 ...

  8. hadoop安装问题

    1. 运行start-dfs.sh启动HDFS守护进程,start-yarn.sh面向YARN的资源器和节点管理器,资源管理器web地址是http://localhost:8080/.输入stop.d ...

  9. 高性能javascript及页面注意事项

    1.少用全局变量 原因:因为作用域链是一个堆栈的结构,所以遵循先进先出的原则,而javascript引擎在解析代码的时候,将全局对象放在栈底,然后向上依次出现的是不同作用域的活动对象(这些活动对象除了 ...

  10. cojs 疯狂的字符串 题解报告

    首先这道题是GT考试的加强版本QAQ 当n<k的时候,答案显然是10^n 当n=k的时候,答案显然是10^n-1 这样就有20分辣 之后我们考虑k<=20的做法 显然设f(i,j)表示前i ...