GSS1 - Can you answer these queries I
You are given a sequence A[1], 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
【题目分析】
乍一看是一个挺裸的线段树的题,然后花了30分钟写完。然后开始了一个小时漫长的交题记录,前前后后交了20多次,最后才发现自己的nowl,nowr,now写成了全局变量,然后各种迷之错误 RE+WA 。直到一个小时之后才改对。
说一下这道题的思路 用线段树去维护一个区间的最大序列,最大的从左端开始的序列,最大的从右端开始的序列,以及和。
那么每次在一个节点处准备合并两个儿子的时候,首先,最大从左的序列就等于max(lch.lans,lch.sum+rch.lans)因为区间的覆盖可能是只有左半部分或者横跨左右两部分。
那么从右端开始也是一样的。最大的子序列和就等于自身从左或从右或者两个儿子中间出现的那一部分,然后计算一下。
小技巧,利用结构体的返回值进行计算会更好。
综上所述,写题时一定要认真。QAQ
#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#define F(i,j,k) for (int i=j;i<=k;++i)
#define LOW -600000000
using namespace std;
struct node{
int l,r,sum,lans,rans,max;
}t[401000];
int data[50010];
int n,q;
void build(int l,int r,int num)
{
t[num].l=l;
t[num].r=r;
if (l==r){
t[num].lans=t[num].rans=t[num].max=t[num].sum=data[l];
return;
}
build(l,(l+r)/2,num*2);
build((l+r)/2+1,r,num*2+1);
t[num].sum=t[num*2].sum+t[num*2+1].sum;
t[num].lans=max(t[num*2].lans,t[num*2].sum+t[num*2+1].lans);
t[num].rans=max(t[num*2+1].rans,t[num*2+1].sum+t[num*2].rans);
t[num].max=max(t[num*2].rans+t[num*2+1].lans,max(t[num*2].max,t[num*2+1].max));
}
node find(int l,int r,int num)
{
node now,nowl,nowr;
if (t[num].r<=r&&t[num].l>=l) return t[num];
int mid=(t[num].l+t[num].r)/2;
if (mid<l) {nowr=find(l,r,num*2+1);
return nowr;
}
else if (mid>=r){
nowl=find(l,r,num*2);
return nowl;
}
nowl=find(l,r,num*2);
nowr=find(l,r,num*2+1);
now.sum=nowl.sum+nowr.sum;
now.lans=max(nowl.lans,nowl.sum+nowr.lans);
now.rans=max(nowr.rans,nowr.sum+nowl.rans);
now.max=max(nowl.rans+nowr.lans,max(nowl.max,nowr.max));
return now;
}
int main()
{
scanf("%d",&n);
F(i,1,n) scanf("%d",&data[i]);
build(1,n,1);
scanf("%d",&q);
F(i,1,q){
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",find(x,y,1).max);
}
}