2022春每日一题:Day 21


题目:[SCOI2007]降雨量

这题比较坑,分几种情况,但是可以总起来说,分开写,两个月份都没出现,maybe,否则如果两个月份都大于[l+1,r-1]的最大值,如果两个月份差值=r-l输出,true,否则maybe,否则false

代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <unordered_map>
const int N = 5e4 + 5;
using namespace std;
int n, m, q, a[N], f[N][20], lg[N], e[N];
unordered_map <int,int> mp;
int ask(int l, int r)
{
	if(l > r)
	    return 0;
	int j = lg[r - l + 1];
	if(a[f[l][j]] > a[f[r - (1<<j) +1][j]])
	    return f[l][j];
	else
	    return f[r - (1<<j) + 1][j];
}
int main()
{
	scanf("%d", &n);
	for(int i = 1; i <= n; i++)
	{
		int x;
	    scanf("%d %d", &x, &a[i]);
	    mp[x] = i;
	    e[i] = x;
	    f[i][0] = i;
	}
	sort(e + 1, e + 1 + n);
	m = unique(e + 1, e + 1 + n) - e - 1;
	scanf("%d", &q);
	for(int i = 2; i <= n; i++)
	    lg[i] = lg[i>>1] + 1;
	for(int j = 1; (1<<j) <= n; j++)
	    for(int i = 1; i + (1<<j) - 1 <= n; i++)
	    {
	    	if(a[f[i][j-1]]>a[f[i + (1<< (j-1))][j-1]])
	    	    f[i][j] = f[i][j-1];
	    	else
	    	    f[i][j] = f[i + (1<< (j-1))][j-1];
	    }
	while(q--)
	{
		int l = 0, r = 0, x, y;
		scanf("%d %d", &x, &y);
		if(x>y)
		{
			puts("false");
			continue;
		}
		if(mp.count(x))
		    l = mp[x];
		if(mp.count(y))
		    r = mp[y];
		if(l == 0 && r == 0)
		{
			puts("maybe");
			continue;
		}
		if(l == 0)
		{
			l = upper_bound(e + 1, e + 1 + n, x) - e;
			int kk = ask(l, r - 1);
			if(a[r] > a[kk])
			    puts("maybe");
			else
			    puts("false");
			continue;
		}
		if(r == 0)
		{
			r = lower_bound(e + 1, e + 1 + n, y) - e - 1;
			int kk = ask(l + 1, r);
			if(a[l] > a[kk])
			    puts("maybe");
			else
			    puts("false");
			continue;
		}
		int kk = ask(l + 1, r - 1);
		if(a[l] < a[r] || a[r] <= a[kk] || a[l] <= a[kk])
		    puts("false");
		else if(r - l == y - x)
		    puts("true");
		else
		    puts("maybe");
	}
	return 0;
}
posted @ 2022-02-26 22:14  __honey  阅读(45)  评论(0)    收藏  举报