• [冬令营Day1 T2]sequence


    题目描述 Description
    给一个长度为N的序列以及Q的询问,每次两个参数l,r,问你序列[l,r]中的最大连续和
    输入描述 Input Description

    一行二个正整数N,Q。
      接下来一行N个整数,描述序列A
      接下来Q行,每行两个参数L,R,描述一个询问。

    输出描述 Output Description
    对于每个询问,输出一行一个整数,描述答案。
    样例输入 Sample Input
    4 3
    1 -2 3 2
    1 4
    1 2
    2 2
    样例输出 Sample Output
    5
    1
    0
    数据范围及提示 Data Size & Hint
    测试点编号 数据范围及特殊说明
    1,2,3 N,Q1000
    4,5,6,7 N,Q10^5
    8,9,10 N10^5,Q10^6

    线段树。对于每个节点,维护三个值。sum,suml,sumr表示该点的最大连续和,最大前缀和和最大后缀和。

    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    using namespace std;
    typedef long long LL;
    inline int read()
    {
        int x=0,f=1;char c=getchar();
        while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
        while(isdigit(c)){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    const int oo=2147000000;
    const int maxn=1000010;
    int n,q,a[maxn],x,y;
    LL pre[maxn],sum[maxn],suml[maxn],sumr[maxn];
    void build(int l,int r,int o)
    {
        if(l==r)
        {
            suml[o]=sumr[o]=sum[o]=pre[r]-pre[l-1];
            return;
        }
        int mid=(l+r)>>1,lo=o<<1,ro=lo+1;
        build(l,mid,lo);
        build(mid+1,r,ro); 
        sum[o]=max(sum[lo],sum[ro]);
        sum[o]=max(sum[o],sumr[lo]+suml[ro]);  
        suml[o]=max(suml[lo],pre[mid]-pre[l-1]+suml[ro]);  
        sumr[o]=max(sumr[ro],pre[r]-pre[mid]+sumr[lo]);
        return;  
    }
    LL queryl(int x,int y,int l,int r,int o)
    {
        if(x==l && y==r) return sumr[o];  
        int mid=(l+r)>>1,lo=o<<1,ro=lo+1;  
        if(x>mid) return queryl(x,y,mid+1,r,ro);    
        else
        {  
            LL tmp=pre[r]-pre[mid]+queryl(x,mid,l,mid,lo);  
            return max(sumr[ro],tmp);  
        }    
    }
    LL queryr(int x,int y,int l,int r,int o) 
    {
        if(x==l && y==r) return suml[o];  
        int mid=(l+r)>>1,lo=o<<1,ro=lo+1;  
        if(y<=mid) return queryr(x,y,l,mid,lo);  
        else
        {  
            LL tmp=pre[mid]-pre[l-1]+queryr(mid+1,y,mid+1,r,ro);  
            return max(suml[lo],tmp);  
        }  
    }
    LL query(int x,int y,int l,int r,int o)
    {
        if(x<=l && y>=r)return sum[o];   
        int mid=(l+r)>>1,lo=o<<1,ro=lo+1;  
        if(y<=mid) return query(x,y,l,mid,lo);  
        else if(x>mid) return query(x,y,mid+1,r,ro);  
        else 
        {  
            LL ls,rs;  
            ls=queryl(x,mid,l,mid,lo);  
            rs=queryr(mid+1,y,mid+1,r,ro);  
            return max(max(query(x,mid,l,mid,lo),query(mid+1,y,mid+1,r,ro)),rs+ls);  
        }  
    }
    int main()
    {
        freopen("sequence.in","r",stdin);
        freopen("sequence.out","w",stdout);
        n=read();q=read();
        for(int i=1;i<=n;i++)a[i]=read(),pre[i]=pre[i-1]+a[i];
        build(1,n,1);
        while(q--)
        {
            x=read();y=read();
            LL tmp=query(x,y,1,n,1);
            if(tmp<0)tmp=0;
            printf("%lld
    ",tmp);
        }
        return 0;
    }

    对于后三个点肯定没戏,毕竟线段树常数那么大。满分做法好像是整体二分,然而并不会,等着以后来填坑吧。

  • 相关阅读:
    jieba库的使用和词云
    类和正则表达
    数据库实践
    自己的第一个网页
    第一个爬虫和测试
    Linux 知识总结
    Python argparse模块基本用法
    Python面向对象编程
    linux Nginx发布基于PHP的WEB
    Linux nginx发布基于python的WEB环境
  • 原文地址:https://www.cnblogs.com/FYH-SSGSS/p/6296380.html
Copyright © 2020-2023  润新知