bzoj1636&bzoj1699【Usaco2007 Jan】Balanced Lineup

1699: [Usaco2007 Jan]Balanced Lineup排队

Time Limit: 5 Sec   Memory Limit: 64 MB
Submit: 1125   Solved: 697
[ Submit][ Status][ Discuss]

Description

每天,农夫 John 的N(1 <= N <= 50,000)头牛总是按同一序列排队. 有一天, John 决定让一些牛们玩一场飞盘比赛. 他准备找一群在对列中为置连续的牛来进行比赛. 但是为了避免水平悬殊,牛的身高不应该相差太大. John 准备了Q (1 <= Q <= 180,000) 个可能的牛的选择和所有牛的身高 (1 <= 身高 <= 1,000,000). 他想知道每一组里面最高和最低的牛的身高差别. 注意: 在最大数据上, 输入和输出将占用大部分运行时间. 

Input

* 第一行: N 和 Q. * 第2..N+1行: 第i+1行是第i头牛的身高.

 * 第N+2..N+Q+1行: 两个整数, A 和 B (1 <= A <= B <= N), 表示从A到B的所有牛.

Output

*第1..Q行: 所有询问的回答 (最高和最低的牛的身高差), 每行一个. 

Sample Input

6 3
1
7
3
4
2
5
1 5
4 6
2 2

Sample Output

6
3
0

HINT

Source

Gold




#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define LL long long
#define pa pair<int,int>
#define MAXN 50005
using namespace std;
int n,q,l,r,t,f[MAXN][20],g[MAXN][20];
int read()
{
	int ret=0,flag=1;
	char ch=getchar();
	while (ch<'0'||ch>'9')
	{
		if (ch=='-') flag='-';
		ch=getchar();
	}
	while (ch>='0'&&ch<='9')
	{
		ret=ret*10+ch-'0';
		ch=getchar();
	}
	return ret*flag;
}
int main()
{
	n=read();q=read();
	F(i,1,n) f[i][0]=g[i][0]=read();
	for(int i=1;(1<<i)<=n;i++) F(j,1,n-(1<<(i-1))+1)
	{
		f[j][i]=max(f[j][i-1],f[j+(1<<(i-1))][i-1]);
		g[j][i]=min(g[j][i-1],g[j+(1<<(i-1))][i-1]);
	}
	F(i,1,q)
	{
		l=read();r=read();
		t=int(log2(r-l+1));
		printf("%d\n",max(f[l][t],f[r-(1<<t)+1][t])-min(g[l][t],g[r-(1<<t)+1][t]));
	}
}


你可能感兴趣的:(bzoj)