A - Can you answer these queries I
A - 你能回答这些问题吗?
点击打开题目链接You are given a sequence A[1], A[2], ..., A[N] . ( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ). A query is defined as follows:
给你一个序列A[1],A[2], ... ,A[N](|A[i]|≤15007,1≤N≤50000)。
查询定义如下:
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.
给定M个查询,你的程序必须输出这些查询的结果。
Input
-
- 输入文件的第一行包含整数N.
- 在第二行中,有N个数字.
- 第三行包含整数M.
- M行跟随,行我包含2个数字xi和yi.
Output
Your program should output the results of the M queries, one query per line. 你的程序应该输出M个查询的结果,每行一个查询。Example
Input: 3 -1 2 3 1 1 2 Output: 2
这道题应该是线段树的算法。(先立一个flag)
其中Query(x,y)= Max{a[i]+a[i+1]+ ... + a [j];x≤i≤j≤y}。
意思是(我不知道)
我还是去看看完全版线段树吧。。
以下是别人的代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int N = 50005;
struct node{
int sum,mx,lx,rx;
inline node(int x = 0){
sum = mx = lx = rx = x;
}
}tree[N<<2];
int ql,qr;
node update(node x, node y){
node ans;
ans.sum = x.sum + y.sum;
ans.mx = max(x.rx + y.lx, max(x.mx, y.mx));
ans.lx = max(x.lx, x.sum + y.lx);
ans.rx = max(y.rx, y.sum + x.rx);
return ans;
}
void build(int id,int l,int r){
if(l == r){
int x;
scanf("%d",&x);
tree[id] = node(x);
return ;
}
int mid = (l+r)>> 1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
tree[id] = update(tree[id<<1], tree[id<<1|1]);
}
node query(int id,int l,int r){
if(ql <= l && r <= qr)
return tree[id];
node x(-INF), y(-INF);
x.sum = y.sum = 0;
int mid = (l+r)>> 1;
if (ql <= mid)
x = query(id<<1,l,mid);
if (qr > mid)
y = query(id<<1|1,mid+1,r);
return update(x,y);
}
int main(){
int n,m;
while(~scanf("%d", &n)){
build(1,1,n);
scanf("%d",&m);
while(m--){
scanf("%d%d",&ql,&qr);
printf("%d\n", query(1,1,n).mx);
}
}
return 0;
}
我去试试看。。
AC了!
于是我给打了些注释。。。
#include<stdio.h>
const int N=50005;
struct node{
int sum,mx,lx,rx;
}tree[N*4];
int ql,qr;
bool max(int a,int b)
{
return a>b?a:b;
}
node update(node x,node y)
{//根据左子树和右子树判断本子树的值
node ans;
ans.sum=x.sum+y.sum;
ans.mx=max(x.rx+y.lx,max(x.mx,y.mx));
ans.lx=max(x.lx,x.sum+y.lx);
ans.rx=max(y.rx,y.sum+x.rx);
return ans;
}
void build(int id,int l,int r)
{
if(l==r)//已找到该节点
{
int x;
scanf("%d",&x);//修改该节点的值
tree[id].sum=tree[id].mx=tree[id].lx=tree[id].rx=x;
return ;
}
int mid=(l+r)/2;//[ ]|[ ]
build(id*2,l,mid);//[l,mid]
build(id*2+1,mid+1,r);//(mid,r]
tree[id]=update(tree[id*2],tree[id*2+1]);//更新该节点的值
}
node query(int id,int l,int r)
{//查找
if(ql<=l&&r<=qr)//如果当前的区间被包含
return tree[id];
node x,y;
x.sum=x.mx=x.lx=x.rx=y.sum=y.mx=y.lx=y.rx=-0x3f3f3f3f;
x.sum=y.sum=0;
int mid=(l+r)/2;//同上
if(ql<=mid)
x=query(id*2,l,mid);
if(qr>mid)
y=query(id*2+1,mid+1,r);
return update(x,y);
}
int main()
{
int n,m;
while(!scanf("%d",&n))
{
build(1,1,n);
scanf("%d",&m);
while(m--)
{
scanf("%d%d",&ql,&qr);
printf("%d\n",query(1,1,n).mx);
}
}
return 0;
}