zoukankan      html  css  js  c++  java
  • SPOJ GSS1_Can you answer these queries I(线段树区间合并)

    SPOJ GSS1_Can you answer these queries I(线段树区间合并)

    标签(空格分隔): 线段树区间合并


    题目链接
    GSS1 - Can you answer these queries I

    You are given a sequence A1, A[2], ..., A[N] . ( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ). A query is defined as follows:
    Query(x,y) = Max { a[i]+a[i+1]+...+a[j] ; x ≤ i ≤ j ≤ y }.
    Given M queries, your program must output the results of these queries.

    Input

    The first line of the input file contains the integer N.
    In the second line, N numbers follow.
    The third line contains the integer M.
    M lines follow, where line i contains 2 numbers xi and yi.
    Output

    Your program should output the results of the M queries, one query per line.
    Example

    Input:
    3
    -1 2 3
    1
    1 2
    Output:
    2

    题意:

    求连续自区间最大和
    

    题解:

    线段树的区间合并可以解决有关连续子区间最值的问题,介绍一下,每一个节点都保存一个此区间的子区间最大值,那么在区间合并的时候就会遇到如何处理包含断点子区间的问题,我们用一个lv保存从左端点开始的连续子区间最值,用rv保存从到右端点结束的连续子区间最值,v表示整个区间的所有元素和,ans表示这个区间的连续子区间的最值。
    那么有合并的时候v要考虑从左孩子的右端点结束加上右孩子的左端点开始,和左孩子和右孩子的ans最大值
    lv要考虑的是左孩子的左端点开始或者是整个左孩子的所有值加上右孩子的从左端点开始的值
    同样rv要考虑的是右孩子的右端点结束或者是整个右孩子的所有值加上左孩子的右端点结束的值
    参考代码如下
    
    void Push(int d){
        st[d].v = st[lc].v+st[rc].v;
        st[d].lv = max(st[lc].lv,st[lc].v+st[rc].lv);
        st[d].rv = max(st[rc].rv,st[rc].v+st[lc].rv);
        st[d].ans = max(max(st[lc].ans,st[rc].ans),st[lc].rv+st[rc].lv);
        return;
    }
    

    代码:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N = 50008;
    #define mid (l+r>>1)
    #define lc d<<1
    #define rc d<<1|1
    
    struct Tr{
        int v,lv,rv,ans;
    }st[N<<2];
    void Push(int d){
        st[d].v = st[lc].v+st[rc].v;
        st[d].lv = max(st[lc].lv,st[lc].v+st[rc].lv);
        st[d].rv = max(st[rc].rv,st[rc].v+st[lc].rv);
        st[d].ans = max(max(st[lc].ans,st[rc].ans),st[lc].rv+st[rc].lv);
        return;
    }
    void build(int l, int r, int d){
        if(l==r){
            scanf("%d",&st[d].ans);
            st[d].v = st[d].lv = st[d].rv = st[d].ans;
            return;
        }
        build(l,mid,lc);
        build(mid+1,r,rc);
        Push(d);
    }
    Tr query(int L, int R, int l, int r, int d)
    {
        if(l==L&&R==r){
            return st[d];
        }
        else if(R<=mid) return query(L,R,l,mid,lc);
        else if(L>mid) return query(L,R,mid+1,r,rc);
        Tr la = query(L,mid,l,mid,lc);
        Tr ra = query(mid+1,R,mid+1,r,rc);
        Tr re;
        re.v = la.v+ra.v;
        re.lv = max(la.lv,la.v+ra.lv);
        re.rv = max(ra.rv,ra.v+la.rv);
        re.ans = max(max(ra.ans,la.ans),la.rv+ra.lv);
        return re;
    }
    int main()
    {
        int n,m;
        int ll,rr;
        while(~scanf("%d",&n))
        {
            build(1,n,1);
            scanf("%d",&m);
            while(m--)
            {
                scanf("%d%d",&ll,&rr);
                Tr fn = query(ll,rr,1,n,1);
                printf("%d
    ",fn.ans);
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    数据恢复:解决ORA600[kghstack_free2][kghstack_err+0068]一例
    Oracle latch闩原理示意图
    MySQL Query Analyzer查询分析器
    Oracle GoldenGate Monitor架构图
    Oracle Row cache lock图解
    没有Metalink账号的同学可以观赏下,My Oracle Support的主界面
    Oracle Goldengate Director软件截面图
    Oracle Unbreakable Enterprise Kernel Faster than Redhat?
    从Win32过渡到MFC
    naked 函数调用
  • 原文地址:https://www.cnblogs.com/shanyr/p/5710152.html
Copyright © 2011-2022 走看看