Can you answer these queries I (线段树)
来源:互联网 发布:福州锐掌网络怎么样 编辑:程序博客网 时间:2024/06/07 01:37
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. ExampleInput:3 -1 2 311 2Output:2
这个题就是给你一个区间 然后再这个区间里面找出一个最大的子区间和
#include<iostream>#include<string.h>#include<algorithm>#include<stdio.h>#define MAXN 50007 *4using namespace std;struct Node{ long left,right; long long lsum,rsum,sum,ans;//lsum代表左端点的最大连续和 //rsum 代表以右结尾的最大连续和 //sum 代表区间和 ans 代表最后的结果}tree[MAXN];void createTree(long rt,long l,long r){ tree[rt].left = l; tree[rt].right = r; if(l==r)//到达叶子节点 { scanf("%lld",&tree[rt].ans); tree[rt].lsum = tree[rt].rsum = tree[rt].sum = tree[rt].ans; return; } //递归创建左子树 long mid = (l+ r)/2; createTree(rt*2,l,mid); createTree(rt*2+1,mid+1,r); /* 利用回溯来更新父节点的信息; */ //左端点的连续最大值有两种情况 一种就是左子树的lsum tree[rt].lsum = tree[rt*2].lsum; //另外一种情况就是左子树的全部sum + 右子树的lsum tree[rt].lsum = max(tree[rt].lsum,tree[rt*2].sum + tree[rt*2+1].lsum); //同理可求右子树 tree[rt].rsum = tree[rt*2+1].rsum; tree[rt].rsum = max(tree[rt].rsum,tree[rt*2+1].sum + tree[rt*2].rsum); //区间和 tree[rt].sum = tree[rt*2].sum + tree[rt*2+1].sum; //结果也是有两种情况的 第一种是取左右子树的某一个最大值 另外一种就是 //最大连续的区间两个子树都有 即 左子树的 rsum + 右子树的 lsum 这种情况也可能会出现最大值 tree[rt].ans = max(tree[rt*2].ans,tree[rt*2+1].ans); tree[rt].ans = max(tree[rt].ans,tree[rt*2].rsum + tree[rt*2+1].lsum);}Node query(long rt,long l,long r)//rt代表根节点 l,r 代表区间的范围{ if(tree[rt].left == l && tree[rt].right == r)//到达叶子节点 { return tree[rt]; } long mid = ( tree[rt].left + tree[rt].right )/2; if(r <= mid ) { return query(rt*2,l,r);//待查询的区间位于左子树 那么就直接查询左子树 } else if(l>mid)//如果l大于mid 那么就是在右子树因为右子树的范围就是mid+1,r { return query(rt*2+1,l,r); } else { Node res; Node lres,rres; //如果不满足以上的情况 那么就是说明了所查区间就是tree[rt]的一个子集 lres = query(rt*2,l,mid); rres = query(rt*2+1,mid+1,r); res.sum = lres.sum + rres.sum; res.lsum = max(lres.lsum,lres.sum + rres.lsum); res.rsum = max(rres.rsum,rres.sum + lres.rsum); res.ans = max(lres.rsum + rres.lsum,max(lres.ans,rres.ans)); return res; }}int main(){ int n,m; scanf("%d",&n); createTree(1,1,n); scanf("%d",&m); while(m--) { int l,r; scanf("%d%d",&l,&r); Node res = query(1,l,r); printf("%lld\n",res.ans); } return 0;}
阅读全文
0 0
- spoj 1043. Can you answer these queries I (线段树)
- 【SPOJ】Can you answer these queries I【线段树】
- [SPOJ GSS1] Can you answer these queries I [线段树]
- 【SPOJ】 1043 Can you answer these queries I 线段树
- Can you answer these queries I (线段树)
- Can you answer these queries?+线段树
- SPOJ 1043 Can you answer these queries I(GSS1 线段树)
- 【线段树】 SPOJ 1043 Can you answer these queries I 区间合并
- 【SPOJ-GSS1】Can you answer these queries I【线段树】【最大子段和】
- SPOJ GSS1 - Can you answer these queries I(线段树维护GSS)
- spoj Can you answer these queries I(线段树 单点更新 区间查询)
- SPOJ GSS1 Can you answer these queries I (线段树求区间最大连续和)
- SPOJ 1043 Can you answer these queries I (超强线段树)
- HDU 4027 Can you answer these queries? 【线段树】
- HDU 4027 Can you answer these queries 线段树
- SPOJ/GSS3:Can you answer these queries III(线段树)
- HDU4027 Can you answer these queries? (线段树)
- hdu4027 Can you answer these queries? 线段树
- selenium设置phantomjs和chrome请求头
- TestNG入门教程-9-断言之HardAssert和SoftAssert
- 5.2.5 重排序方法
- 移动端左滑删除功能
- sdut 3361迷宫探索dfs
- Can you answer these queries I (线段树)
- linux 安装tensorflow
- varchar和Nvarchar区别
- QML使用PinchArea实现捏拉缩放与旋转并单手拖放控件
- String Permutation
- 投筛子游戏
- python常用模块整理
- 小白学数据结构——二、树与堆(基本概念及二叉树、二叉堆的python实现)
- word转pdf代码