P2471 [SCOI2007]降雨量

题面

区间最值问题。

比较习惯用线段树维护区间最值qwq。

大力讨论各种情况的成立与否即可。

#include <bits/stdc++.h>
using namespace std;

template<typename temp>
temp read(temp &x){
	x = 0;temp f = 1;char ch;
	while(!isdigit(ch = getchar())) (ch == '-') and (f = -1);
	for(x = ch^48; isdigit(ch = getchar()); x = (x<<1)+(x<<3)+(ch^48));
	return x *= f;
}
template <typename temp, typename ...Args>
void read(temp& a, Args& ...args){
	read(a), read(args...);
}

const int maxn = 5e5+10;
	
int n, m;
int a[maxn], b[maxn];

struct seg_tree{
	#define ls (now << 1)
	#define rs (now<<1|1)
	#define mid ((l+r)>>1)
	struct nodes{
		int l, r, num, id;
	}node[maxn<<2];
	void max_node(nodes &x, nodes &y){if(x.num<y.num) x.num = y.num, x.id = y.id;return;}
	void up(int now){return max_node(node[now], node[ls]), max_node(node[now], node[rs]);}
	void build(int l, int r, int now){
		node[now].l = l, node[now].r = r;
		if(l == r) return (void)(node[now].id = a[l], node[now].num = b[l]);
		build(l, mid, ls), build(mid+1, r, rs);
		return up(now);
	}
	void quary(int l, int r, int now, pair<int,int> &ans){
		if(r < node[now].l or node[now].r < l) return;
		if(l <= node[now].l and node[now].r <= r){if(node[now].num > ans.second) ans.second = node[now].num, ans.first = node[now].id;}
		else quary(l, r, ls, ans), quary(l, r, rs, ans);
		return up(now);
	}
}tree;

signed main(){
	read(n);
	for(int i = 1; i <= n; i ++) read(a[i], b[i]);
	tree.build(1, n, 1);
	read(m);
	for(int x, y; m; m --){
		read(x, y);
		if(x >= y){
			printf("false
");
			continue;
		}
		int l = lower_bound(a+1, a+n+1, x)-a, r = lower_bound(a+1, a+n+1, y)-a;
		bool visl = (a[l] == x), visr = (a[r] == y);
		pair<int,int> ans;
		if(!visl) l--;
		if(l+1 <= r-1) tree.quary(l+1, r-1, 1, ans);
		if((ans.second >= b[r] and visr) or (b[l] < b[r] and visr and visl) or (ans.second >= b[l] and visl)){
			printf("false
");
		}else{
			if((r-l != a[r]-a[l]) or !visl or !visr) printf("maybe
");
			else printf("true
");
		}
	}
	return 0;
}
原文地址:https://www.cnblogs.com/Vanyun/p/13561847.html