[BZOJ1067/Luogu2471][SCOI2007]降雨量

题目链接:

BZOJ1067

Luogu2471

来了来了,BZOJ著名题目

(Juruo)少有的(1A)

很明显的一个分类讨论题,分以下(5)中情况来讨论。

(l,r)为询问的两个年份,(Rain_i)表示(i)年的雨量。


  • (1.)答案为(true)

    • (Rain_lsim Rain_r)已知

    • (Rain_r<Rain_l)

    • (Rain_r>max{Rain_{l+1}sim Rain_{r-1}})


  • (2.)答案为(false)的一种:(Rain_l,Rain_r)已知

    • (Rain_rge Rain_l)(Rain_rlemax{Rain_{l+1}sim Rain_{r-1}})

  • (3.)答案为(false)的一种:(Rain_l)已知

    • (Rain_l-max{Rain_{l+1}sim Rain_{r-1}}le 2)(没有足够的空隙留给(Rain_r))

  • (4.)答案为(false)的一种:(Rain_r)已知

    • (Rain_rle max{Rain_{l+1}sim Rain_{r-1}})

  • (5.)其他情况均为(maybe)

真简单

关于(max)查询我用的(ST)表,好写,常数小。

#include <cstdio>
#include <algorithm>

int n,m;
int Year[50005],Rain[50005];
int Log[50005],f[50005][17];

inline int Max(int l,int r)
{
	if(l>r)return -1;
	int k=Log[r-l+1];
	return std::max(f[l][k],f[r-(1<<k)+1][k]);
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;++i)scanf("%d%d",&Year[i],&Rain[i]);
	for(int i=1;i<=n;++i)f[i][0]=Rain[i];
	for(int i=2;i<=n;++i)Log[i]=Log[i>>1]+1;//预处理Log
	for(int k=1;(1<<k)<=n;++k)
		for(int i=1;i+(1<<k)-1<=n;++i)
			f[i][k]=std::max(f[i][k-1],f[i+(1<<(k-1))][k-1]);
	scanf("%d",&m);
	for(int l,r;m--;)
	{
		scanf("%d%d",&l,&r);
		int p1=std::lower_bound(Year+1,Year+n+1,l)-Year;
		int p2=std::lower_bound(Year+1,Year+n+1,r)-Year;
		if(Year[p1]==l&&Year[p2]==r&&p2-p1==r-l&&Rain[p2]<Rain[p1]&&Rain[p2]>Max(p1+1,p2-1))
			puts("true");
		else if(Year[p1]==l&&Year[p2]==r&&(Rain[p2]>=Rain[p1]||Rain[p2]<=Max(p1+1,p2-1)))
			puts("false");
		else if(Year[p1]==l&&Year[p2]!=r&&Rain[p1]-Max(p1+1,p2-1)<2)
			puts("false");
		else if(Year[p1]!=l&&Year[p2]==r&&Rain[p2]<=Max(p1,p2-1))
			puts("false");
		else
			puts("maybe");
	}
	return 0;
}

(Upadte:)似乎很多人没有考虑第(3)种情况?

原文地址:https://www.cnblogs.com/LanrTabe/p/10151573.html