SPOJ GSS1 Can you answer these queries I

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);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
洛谷的SPOJ需要注册一个SPOJ账号并进行绑定才能进行交题。您可以按照以下步骤进行注册: 1. 打开洛谷网站(https://www.luogu.com.cn/)并登录您的洛谷账号。 2. 在网站顶部导航栏中找到“题库”选项,将鼠标悬停在上面,然后选择“SPOJ”。 3. 在SPOJ页面上,您会看到一个提示,要求您注册SPOJ账号并进行绑定。点击提示中的链接,将会跳转到SPOJ注册页面。 4. 在SPOJ注册页面上,按照要求填写您的用户名、密码和邮箱等信息,并完成注册。 5. 注册完成后,返回洛谷网站,再次进入SPOJ页面。您会看到一个输入框,要求您输入刚刚注册的SPOJ用户名。输入用户名后,点击“绑定”按钮即可完成绑定。 现在您已经成功注册并绑定了SPOJ账号,可以开始在洛谷的SPOJ题库上刷题了。祝您顺利完成编程练习!\[1\]\[2\] #### 引用[.reference_title] - *1* *3* [(洛谷入门系列,适合洛谷新用户)洛谷功能全解](https://blog.csdn.net/rrc12345/article/details/122500057)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [luogu p7492 序列](https://blog.csdn.net/zhu_yin233/article/details/122051384)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值