NC20259 [SCOI2007]降雨量
题目
题目描述
我们常常会说这样的话:“X年是自Y年以来降雨量最多的”。它的含义是X年的降雨量不超过Y年,且对于任意 Y<Z<X,Z年的降雨量严格小于X年。
例如2002,2003,2004和2005年的降雨量分别为4920,5901,2832和3890, 则可以说“2005年是自2003年以来最多的”,但不能说“2005年是自2002年以来最多的”由于有些年份的降雨量未知,有的说法是可能正确也可以不正确的。
输入描述
输入仅一行包含一个正整数n,为已知的数据。
以下n行每行两个整数yi和ri,为年份和降雨量,按照年份从小 到大排列,即yi<yi+1。
下一行包含一个正整数m,为询问的次数。
以下m行每行包含两个数Y和X,即询问“X年是自Y年以来降雨量最多的。”这句话是必真、必假还是“有可能”。
输出描述
对于每一个询问,输出true,false或者maybe。
示例1
输入
6 2002 4920 2003 5901 2004 2832 2005 3890 2007 5609 2008 3024 5 2002 2005 2003 2005 2002 2007 2003 2007 2005 2008
输出
false true false maybe false
备注
100%的数据满足:
题解
知识点:线段树,离散化。
数据范围显然需要离散化,然后就是普通的区间最大值查询,但是分类讨论年份左右端点会很麻烦:
- 左右是完全相等的,直接
true
。 - 左右都不存在,直接
maybe
。 - 左存在右不存在,如果已知的区间长度为 或除去右端点的区间最大值小于右端点值,则
maybe
;否则false
。 - 左不存在右存在,如果已知的区间长度为 或除去左端点的区间最大值小于左端点值,则
maybe
;否则false
。 - 左右都存在,若左端点值大于等于右端点值,且区间长度为1或2或除去左右端点的区间最大值小于右端点值,则继续判断;否则
false
。若满足条件,则若已知的区间长度等于实际年份跨度,则true
;否则maybe
。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> using namespace std; using ll = long long; struct T { int mx; static T e() { return { (int)-2e9 }; } friend T operator+(const T &a, const T &b) { return { max(a.mx,b.mx) }; } }; template<class T> class SegmentTree { int n; vector<T> node; T query(int rt, int l, int r, int x, int y) { if (r < x || y < l) return T::e(); if (x <= l && r <= y) return node[rt]; int mid = l + r >> 1; return query(rt << 1, l, mid, x, y) + query(rt << 1 | 1, mid + 1, r, x, y); } public: SegmentTree() {} SegmentTree(const vector<T> &src) { init(src); } void init(const vector<T> &src) { assert(src.size()); n = src.size() - 1; node.assign(n << 2, T::e()); function<void(int, int, int)> build = [&](int rt, int l, int r) { if (l == r) return node[rt] = src[l], void(); int mid = l + r >> 1; build(rt << 1, l, mid); build(rt << 1 | 1, mid + 1, r); node[rt] = node[rt << 1] + node[rt << 1 | 1]; }; build(1, 1, n); } T query(int x, int y) { return query(1, 1, n, x, y); } }; int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int n; cin >> n; vector<T> a(n + 1); vector<int> y_src(n + 1); for (int i = 1;i <= n;i++) { int y, r; cin >> y >> r; a[i] = { r }; y_src[i] = y; } auto get = [&](int x)->int { return lower_bound(y_src.begin() + 1, y_src.end(), x) - y_src.begin(); }; SegmentTree<T> sgt(a); int m; cin >> m; while (m--) { int l, r; cin >> l >> r; if (l > r) { cout << "false" << '\n'; continue; }//* 题意不明 if (l == r) { cout << "true" << '\n'; continue; } int rkl = get(l), rkr = get(r); if (y_src[rkl] != l && y_src[rkr] != r) cout << "maybe" << '\n'; else if (y_src[rkl] != l) { if (rkl == rkr || sgt.query(rkl, rkr - 1).mx < a[rkr].mx) cout << "maybe" << '\n'; else cout << "false" << '\n'; } else if (y_src[rkr] != r) { if (rkl + 1 == rkr || sgt.query(rkl + 1, rkr - 1).mx < a[rkl].mx) cout << "maybe" << '\n'; else cout << "false" << '\n'; } else if (a[rkl].mx >= a[rkr].mx && (rkl == rkr || rkl + 1 == rkr || sgt.query(rkl + 1, rkr - 1).mx < a[rkr].mx)) { if (r - l > rkr - rkl) cout << "maybe" << '\n'; else cout << "true" << '\n'; } else cout << "false" << '\n'; } return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/17354226.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!