线段树

#include <iostream>
#include <cstdio>
using namespace std;

const int MAX = 99999999;
const int MIN = -MAX;
int n, L, U;
int segment[33000 * 4];
int sum[33000];

void build(int node, int begin, int end)
{
	if (begin == end)
		segment[node] = sum[begin];
	else
	{
		int mid = (begin + end) / 2;
		build(2 * node, begin, mid);
		build(2 * node + 1, mid + 1, end);

		if (segment[2 * node] > segment[2 * node + 1])
			segment[node] = segment[2 * node];
		else
			segment[node] = segment[2 * node + 1];
	}
}

int query(int node, int begin, int end, int left, int right)
{
	if (left > end || right < begin)
		return MIN;
	if (begin >= left && end <= right)
		return segment[node];

	int mid = (begin + end) / 2;
	int p1 = query(2 * node, begin, mid, left, right);
	int p2 = query(2 * node + 1, mid + 1, end, left, right);

	if (p1 > p2)
		return p1;
	else
		return p2;
}

int main()
{

	while (scanf("%d", &n) && n)
	{
		scanf("%d%d", &L, &U);
		
		sum[0] = 0;
		for (int i = 1; i <= n; i++)
		{
			scanf("%d", &sum[i]);
			sum[i] += sum[i-1];
		}
		build(1, 0, n);

		int minSum = MAX;
		for (int i = L; i <= n; i++)
		{
			//I - L, I - U的最大值
			int l = i - U;
			int r = i - L;
			if (l < 0)
			{
				l = 0;
			}

			int value = sum[i] - query(1, 0, n, l, r);
			if (value < minSum)
				minSum = value;
		}
		cout << minSum << endl;
	}

	return 0;
}



对应例题:soj 1800

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值