[冬令营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,Q≤1000
4,5,6,7 N,Q≤10^5
8,9,10 N≤10^5,Q≤10^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\n",tmp);
    }
    return 0;
}

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

时间: 2024-08-08 22:09:43

[冬令营Day1 T2]sequence的相关文章

洛谷P2661 信息传递==coedevs4511 信息传递 NOIP2015 day1 T2

P2661 信息传递 题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自己的信息传递对象).当有人从别人口中得知自己的生日时,游戏结束.请问该游戏一共可以进行几轮? 输入输出格式 输入格式: 输入共2行. 第1

信息传递 NOIP2015 day1 T2

题文: 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自己的信息传递对象).当有人从别人口中得知自己的生日时,游戏结束.请问该游戏一共可以进行几轮? 输入共2行. 第1行包含1个正整数n表示n个人. 第2行包含n个用空

【 NOIP2015 DAY1 T2 信息传递】带权并查集

题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一轮中,所有人会同时将自己当前所知的生日信息告诉各自的信息传递对象(注意:可能有人可以从若干人那里获取信息,但是每人只会把信息告诉一个人,即自己的信息传递对象).当有人从别人口中得知自己的生日时,游戏结束.请问该游戏一共可以进行几轮? 输入输出格式 输入格式: 输入共2行. 第1行包含1个正整数n表示

2016NOI冬令营day1

感冒了!!!: ( 上午听 picks 讲多项式导论(所有内容均不考)只听懂了那个O(n1.585)的多项式乘法算法 : ( 安装好了弹幕!太厉害了(有电脑的都在刷弹幕) :  ( 中午吃的不错 : )睡了半小时午觉居然睡着了:| 下午听 茹逸夫 讲形式语言与自动机(所有内容均不考).一开始感觉能听懂,挺有兴趣的,听了一大半之后开始讲一些神乎其神的东西了,同时我头又很痛,又想睡觉,所以根本听不进去 : ( 晚饭之前回了一趟寝室,去食堂去晚了,没吃到什么好东西 : ( 晚上来到了南山机房(所谓的上

【NOIP之旅】NOIP2014 day1 T2 联合权值

2.联合权值 (link.cpp/c/pas) [问题描述] 无向连通图G有n个点,n-1条边.点从1到n依次编号,编号为i的点的权值为Wi  ,每条边的长度均为1.图上两点(u, v)的距离定义为u点到v点的最短距离.对于图G上的点对(u, v),若它们的距离为2,则它们之间会产生Wu×Wv的联合权值. 请问图G上所有可产生联合权值的有序点对中,联合权值最大的是多少?所有联合权值之和是多少? [输入] 输入文件名为link.in. 第一行包含1个整数n. 接下来n-1行,每行包含2个用空格隔开

noi2015 day1 T2软件包管理器

noi2015 软件包管理器 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个软件包的安装所依赖的其它软件包),完成所有的配置.Debian/Ubuntu使用的apt-get,Fedora/CentOS使用的yum,以及OSX下可用的homebrew都是优秀的软件包管理器. 你决定设计你自己的软件包管理器.不可避免地,你要解决软件包

NOIP 2012 提高组 DAY1 T2 国王游戏

题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右 手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排 成一排,国王站在队伍的最前面.排好队后,所有的大臣都会获得国王奖赏的若干金币,每 位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右 手上的数,然后向下取整得到的结果. 国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序, 使得获得奖赏最多的大臣,所获奖赏尽可能的少

福建省冬令营 Day2 T2

题解: 1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cstdio> 6 #include<cmath> 7 using namespace std; 8 typedef long long lol; 9 const lol mo = 1e9 + 7; 10 const int me = 200

NOIP 2011 Day1 T2 选择客栈

1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<string> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #include<stack> 10 #include<iomanip>