降雨量

发布时间 2023-10-12 19:04:38作者: 不o凡

降雨量

可以利用线段树,st表
模板+模拟
思路:
1.利用st表,先算出每个区间内的最大值
2.模拟:

2.1因为true要求的条件更加苛刻,所以先对true分析:
1.两端年份存在 2.年份连续 3.俩年份内的最大值小于右端 4.左端降雨量小于等于右端

2.2 对false分析:
1.特判:如果左端不存在需要左移,因为这个点在计算的范围内如果你不用lower_bound当我没说
2.如果左端存在,则:中间的值要大于等于左端,这样右端只可能大于左端false,如果小于还是false
3.如果右端存在,则:中间的值要大于等于右端
4.如果两端都存在,则:右端>左端

2.3 如果都不满足,则maybe

还要注意些条件,都在代码里

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long//开LL,不然运行错误
const int N = 1e5 + 10;
int f[N][22];
int y[N], w[N];
void st(int n) {
	for (int i = 1; i <= n; i++) f[i][0] = w[i];
	for (int j = 1; j <= 20; j++) {
		for (int i = 1; i+(1LL<<j)-1 <= n; i++)
			f[i][j] = max(f[i][j - 1], f[i + (1LL << (j-1))][j - 1]);//记住里面的顺序(1<<(j-1)),经常出错
	}
}
signed main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int n, m;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> y[i] >> w[i];
	}
	st(n);
	cin >> m;
	while (m--) {
		int xx, yy;
		cin >> yy >> xx;
		int dr = lower_bound(y + 1, y + 1 + n, xx)-y;//X右边端点
		int dl = lower_bound(y + 1, y + 1 + n, yy) - y;//Y左边端点
		//int lx = (dr - dl) == xx - yy;//是否连续
		//判断两年份是否存在,否则会出现假连续的情况:如两年份都不存在
		int bl = yy == y[dl];
		int br = xx == y[dr];
		//特判
		if (!bl) dl--;//防止这个数没有算
		//st表
		int k = log2(dr - dl-1);
		int v = 0;//求区间内的最大降雨量
		if(dl+1<=dr-1) v= max(f[dl + 1][k], f[dr - (1LL << k)][k]);//一定要有这个条件特判,不然只能对一半。中间值存在
		//输出
		if (bl && br && (dr - dl) == xx - yy && v < w[dr] && w[dr] <= w[dl]) cout << "true\n";
		else if ((bl&& v >= w[dl]) || (br && v >= w[dr]) || (bl && br && w[dl] < w[dr])) cout << "false\n";
		else cout << "maybe\n";
	}
	return 0;
}