zoukankan      html  css  js  c++  java
  • SP1043 GSS1

    题目描述

    给出了序列A[1],A[2],…,A[N]。 (a[i]≤15007,1≤N≤50000)。查询定义如下: 查询(x,y)=max{a[i]+a[i+1]+...+a[j];x≤i≤j≤y}。 给定M个查询,程序必须输出这些查询的结果。

    输入输出格式

    输入格式:

    • 输入文件的第一行包含整数N。
    • 在第二行,N个数字跟随。
    • 第三行包含整数M。
    • M行跟在后面,其中第1行包含两个数字xi和yi。

    输出格式:

    您的程序应该输出M查询的结果,每一行一个查询。

    思路:

    我们做这道题首先应该想的,是两个区间如何合并

    很显然,合并后最大子段和,要么是原来左儿子的,要么是原来右儿子的

    还有一种可能是左右两个儿子合并后在中间新生成的

    所以,每个节点维护四个元素

    分别表示他所管辖的区间和,他所管辖的区间中的最大连续子段和

    从左起最大连续子段和(意思是子段的左端点一定是区间的左端点)

    从右起最大连续子段和(意思同上)

    此时我们可以这样转移:

    sum(和)就不用说了

    这一层的从左起最大连续子段和=max(左儿子的从左起最大连续子段和,左儿子的和+右儿子的从左起最大连续子段和)

    这一层的从左起最大连续子段和方法同上

    这一层的最大连续子段和=max(左儿子的最大连续子段和,右儿子的最大连续子段和,(左儿子从右起的最大连续字段和+右儿子从左起的最大连续子段和(也就是合并后生成的中间最大子段)))

    OK,任务完成

    查询同理

    代码:

    //这里我将建树当成更改节点值
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define rii register int i
    #define rij register int j
    #define inf 1073741824
    #define rs 65536
    using namespace std;
    struct nod{
        int lm,rm,maxn,sum;
    }x[6000005];
    int n,q,cz,x1,y1;
    void add(int wz,int l,int r,int val,int bh)
    {
        if(l==r&&l==wz)
        {
            x[bh].maxn=val;
            x[bh].lm=val;
            x[bh].rm=val;
            x[bh].sum=val;
            return;
        }
        int ltt=(l+r)/2;
        if(wz<=ltt)
        {
            add(wz,l,ltt,val,bh*2);
        }
        else
        {
            add(wz,ltt+1,r,val,bh*2+1);
        }
        x[bh].sum=x[bh*2].sum+x[bh*2+1].sum;
        x[bh].lm=max(x[bh*2].lm,x[bh*2].sum+x[bh*2+1].lm);
        x[bh].rm=max(x[bh*2+1].rm,x[bh*2+1].sum+x[bh*2].rm);
        x[bh].maxn=max(x[bh*2].maxn,max(x[bh*2+1].maxn,x[bh*2].rm+x[bh*2+1].lm));
    }
    nod query(int l,int r,int nl,int nr,int bh)
    {
        nod an,bn;
        if(l<nl)
        {
            l=nl;
        }
        if(r>nr)
        {
            r=nr;
        }
        if(nl==l&&nr==r)
        {
            an=x[bh];
            return an;
        }
        int ltt=(nl+nr)/2;
        if(l<=ltt&&r<=ltt)
        {
            return an=query(l,r,nl,ltt,bh*2);
        }
        if(r>ltt&&l>ltt)
        {
            return bn=query(l,r,ltt+1,nr,bh*2+1);
        }
        else
        {
            an=query(l,r,nl,ltt,bh*2);
            bn=query(l,r,ltt+1,nr,bh*2+1);
            an.maxn=max(an.maxn,max(bn.maxn,an.rm+bn.lm));
            an.lm=max(an.lm,an.sum+bn.lm);
            an.rm=max(bn.rm,bn.sum+an.rm);
            an.sum=an.sum+bn.sum;
            return an;
        }
        
    }
    int main()
    {
    //    freopen("brs.in","r",stdin);
    //    freopen("brs.out","w",stdout);
        for(rii=1;i<=150005;i++)
        {
            x[i].lm=-inf;
            x[i].rm=-inf;
            x[i].maxn=-inf;
        }
        scanf("%d",&n);
        for(rii=1;i<=n;i++)
        {
            int ltt;
            scanf("%d",&ltt);
            add(i,1,rs,ltt,1);
        }
        scanf("%d",&q);
        for(rii=1;i<=q;i++)
        {
            scanf("%d%d",&x1,&y1);
            nod ans=query(x1,y1,1,rs,1);
            printf("%d
    ",ans.maxn);
        }
    }
  • 相关阅读:
    Java静态方法中使用注入类
    Java FTP辅助类
    Java SFTP辅助类
    MyBatis学习总结——批量查询
    MyBatis学习总结—实现关联表查询
    Redis集群搭建与简单使用
    SQL管理工具
    MySQL锁机制
    MySQL权限管理
    yii框架下使用redis
  • 原文地址:https://www.cnblogs.com/ztz11/p/9343366.html
Copyright © 2011-2022 走看看