题目描述

给出了序列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[];
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)/;
if(wz<=ltt)
{
add(wz,l,ltt,val,bh*);
}
else
{
add(wz,ltt+,r,val,bh*+);
}
x[bh].sum=x[bh*].sum+x[bh*+].sum;
x[bh].lm=max(x[bh*].lm,x[bh*].sum+x[bh*+].lm);
x[bh].rm=max(x[bh*+].rm,x[bh*+].sum+x[bh*].rm);
x[bh].maxn=max(x[bh*].maxn,max(x[bh*+].maxn,x[bh*].rm+x[bh*+].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)/;
if(l<=ltt&&r<=ltt)
{
return an=query(l,r,nl,ltt,bh*);
}
if(r>ltt&&l>ltt)
{
return bn=query(l,r,ltt+,nr,bh*+);
}
else
{
an=query(l,r,nl,ltt,bh*);
bn=query(l,r,ltt+,nr,bh*+);
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=;i<=;i++)
{
x[i].lm=-inf;
x[i].rm=-inf;
x[i].maxn=-inf;
}
scanf("%d",&n);
for(rii=;i<=n;i++)
{
int ltt;
scanf("%d",&ltt);
add(i,,rs,ltt,);
}
scanf("%d",&q);
for(rii=;i<=q;i++)
{
scanf("%d%d",&x1,&y1);
nod ans=query(x1,y1,,rs,);
printf("%d\n",ans.maxn);
}
}

SP1043 GSS1 - Can you answer these queries I(线段树,区间最大子段和(静态))的更多相关文章

  1. SP1043 GSS1 - Can you answer these queries I 线段树

    问题描述 LG-SP1043 题解 GSS 系列第一题. \(q\) 个询问,求 \([x,y]\) 的最大字段和. 线段树,维护 \([x,y]\) 的 \(lmax,rmax,sum,val\) ...

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

    SPOJ GSS1_Can you answer these queries I(线段树区间合并) 标签(空格分隔): 线段树区间合并 题目链接 GSS1 - Can you answer these ...

  3. SPOJ GSS1 - Can you answer these queries I(线段树维护GSS)

    Can you answer these queries I SPOJ - GSS1 You are given a sequence A[1], A[2], -, A[N] . ( |A[i]| ≤ ...

  4. HDU 4027—— Can you answer these queries?——————【线段树区间开方,区间求和】

    Can you answer these queries? Time Limit:2000MS     Memory Limit:65768KB     64bit IO Format:%I64d & ...

  5. HDU 4027 Can you answer these queries?(线段树区间开方)

    Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65768/65768 K ...

  6. SPOJ GSS1 Can you answer these queries I[线段树]

    Description You are given a sequence A[1], A[2], ..., A[N] . ( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ). A q ...

  7. SPOJ GSS1 Can you answer these queries I ——线段树

    [题目分析] 线段树裸题. 注意update的操作,写结构体里好方便. 嗯,没了. [代码] #include <cstdio> #include <cstring> #inc ...

  8. HDU - 4027 Can you answer these queries?(线段树区间修改)

    https://cn.vjudge.net/problem/HDU-4027 题意 给一个有初始值的数组,存在两种操作,T=0时将[L,R]的值求平方根,T=1时查询[L,R]的和. 分析 显然不符合 ...

  9. 线段树 SP1043 GSS1 - Can you answer these queries I

    SP1043 GSS1 - Can you answer these queries I 题目描述 给出了序列A[1],A[2],-,A[N]. (a[i]≤15007,1≤N≤50000).查询定义 ...

  10. GSS4 2713. Can you answer these queries IV 线段树

    GSS7 Can you answer these queries IV 题目:给出一个数列,原数列和值不超过1e18,有两种操作: 0 x y:修改区间[x,y]所有数开方后向下调整至最近的整数 1 ...

随机推荐

  1. 封装http请求键值对的js函数

    //封装http请求键值对的函数 function Map() { this.keys = new Array(); this.data = {}; //添加键值对 this.put = functi ...

  2. 折半查找——Java实现

    一.查找思想 折半查找 也称为二分查找,是一种效率较高的查找方法,查找时要求表中的节点按关键字的大小排序,并且要求线性表顺序存储. 首先用要查找的关键字值(key)与中间位置结点的关键字值(arr[m ...

  3. Thrift笔记(四)--Thrift client源码分析

    thrift文件 namespace java com.gxf.demo namespace py tutorial typedef i32 int // We can use typedef to ...

  4. android 短期计划

    http://www.jianshu.com/p/2a9fcf3c11e4 http://www.jianshu.com/p/5f6d79323923 activity启动模式: http://www ...

  5. C#+ObjectArx CAD二次开发(2)

    前面开了一个头,这里添加几个功能的实现, //添加图层 private void LoadLayer() { Document acDoc = Application.DocumentManager. ...

  6. PAT 1043 Is It a Binary Search Tree

    #include <cstdio> #include <climits> #include <cstdlib> #include <vector> co ...

  7. socket应用

    socket的使用 socket.socket(网络层ip协议蔟,传输层协议类型,默认协议) # server.py # 导入模块 import socket # 实例化服务器,使用ipv4协议,tc ...

  8. iframe中插入代码并执行

    最近有需求通过iframe插入代码.有蛮多方法,如下: 1 var iframe = document.getElementById('previewUrl'); 2 iframe.src = 'ab ...

  9. 自适应布局下echarts引起页面跳帧

    项目上突然遇到一个问题,鼠标快速滑动有echarts画的饼图时,页面出现了跳帧.布局的高度突然发生变化然后恢复正常.高度怎么会变化呢?都是按百分比来的啊? 经过一番仔细观察,在跳帧的时候页面底部闪过了 ...

  10. canvas入门(一)

    canvas是HTML 5中非常重要的一个标签,关于它的功能和使用方法在这我就不一一细谈了,毕竟网上相关知识太多,而且自认为如果是我总结那些知识会让读者看的更乱,所以我就不白费力气了,贴上链接:htt ...