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;
    }
    
    
  • 相关阅读:
    关于celery踩坑
    关于git的分批提交pull requests流程
    SymGAN—Exploiting Images for Video Recognition: Heterogeneous Feature Augmentation via Symmetric Adversarial Learning学习笔记
    AFN—Larger Norm More Transferable: An Adaptive Feature Norm Approach for Unsupervised Domain Adaptation学习笔记
    Learning to Transfer Examples for Partial Domain Adaptation学习笔记
    Partial Adversarial Domain Adaptation学习笔记
    Partial Transfer Learning with Selective Adversarial Networks学习笔记
    Importance Weighted Adversarial Nets for Partial Domain Adaptation学习笔记
    Exploiting Images for Video Recognition with Hierarchical Generative Adversarial Networks学习笔记
    improved open set domain adaptation with backpropagation 学习笔记
  • 原文地址:https://www.cnblogs.com/shanyr/p/5710152.html
Copyright © 2011-2022 走看看