为什么要写博客?

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



                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值