【POJ 3264】平衡的阵容【分块】

题目大意:

题目链接:http://poj.org/problem?id=3264
给出一个长度为 n n n的数列,求第 l l l位到第 r r r位的最大值减最小值。


思路:

RMQ做法:https://blog.csdn.net/SSL_ZYC/article/details/80422589
这道题也可以用分块做。当然线段树主席树也都可以。
简直比分块模板还简单。因为没有修改操作。
要求 l l l r r r之间的最小值,那么就先将这个数列分成 n \sqrt{n} n 块,每块初始化出一个最大值和最小值,时间复杂度 O ( n ) O(n) O(n)
接着对于每次询问,就用分块求出询问区间的最大值和最小值,再两者相减,即为答案。


代码:

此代码在POJ上可以AC,但洛谷只能拿40分,应该是编译环境的问题。

#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#define N 50100
using namespace std;

int n,m,a[N],t,x,y,L[N],R[N],pos[N],maxn[N],minn[N];

int find_max(int l,int r)  //暴力求l到r之间的最大值
{
	int ans=0;
	for (int i=l;i<=r;i++)
	 ans=max(ans,a[i]);
	return ans;
}

int find_min(int l,int r)  //暴力求l到r之间的最小值
{
	int ans=1e9;
	for (int i=l;i<=r;i++)
	 ans=min(ans,a[i]);
	return ans;
}

int Max(int l,int r)  //求询问区间的最大值
{
	int q=pos[l],p=pos[r];
	if (q==p) return find_max(l,r);
	int ans=max(find_max(l,R[q]),find_max(L[p],r));
	for (int i=q+1;i<p;i++)
	 ans=max(ans,maxn[i]);
	return ans;
}

int Min(int l,int r)  //求询问区间的最小值
{
	int q=pos[l],p=pos[r];
	if (q==p) return find_min(l,r);
	int ans=min(find_min(l,R[q]),find_min(L[p],r));
	for (int i=q+1;i<p;i++)
	 ans=min(ans,minn[i]);
	return ans;
}

int ask(int l,int r)
{
	return Max(l,r)-Min(l,r);
}

int main()
{
	memset(minn,0x3f3f3f3f,sizeof(minn));
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++)
	 scanf("%d",&a[i]);
	t=(int)sqrt(n);
	for (int i=1;i<=t;i++)
	{
		L[i]=R[i-1]+1;
		R[i]=i*t;
	}
	if (R[t]<n)
	{
		L[++t]=R[t-1]+1;
		R[t]=n;
	}
	for (int i=1;i<=t;i++)
	 for (int j=L[i];j<=R[i];j++)
	 {
	 	pos[j]=i;
	 	maxn[i]=max(maxn[i],a[j]);
	 	minn[i]=min(minn[i],a[j]);  //初始化每个区间的最大值和最小值
	 }
	while (m--)
	{
		scanf("%d%d",&x,&y);
		printf("%d\n",ask(x,y));
	}
	return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值