本文并非最优解,但能通过。
一、题目链接
P10288 [GESP样题 八级] 区间 - 洛谷
二、解题思路
**本题的大意就是求出a[l~r]间x出现的次数,由于数据较大、较多,所以暴力容易超时。**
首先新建一个mp,mp[x]是一个vector,里面存放从前到后x出现的下标。
map<int, vector<int> > mp;
如下,在输入时录入每个下标。
for (int i = 1; i <= n; i++) {int x;cin >> x;mp[x].push_back(i); }
接下来就是查询:
首先认识两个函数
简单用法: upper_bound(起点, 终点, x); 返回从起点到终点第一个【大于】x的位置 返回类型是iterator。 例如upper_bound(v.begin(), v.end(), x)lower_bound(起点, 终点, x); 返回从起点到终点第一个【不小于】x的位置 返回类型是iterator。 例如lower_bound(v.begin(), v.end(), x)!!!如果找不到, 返回最后一个元素后面的位置
所以:
while (q--) {int l, r, x;cin >> l >> r >> x;cout << upper_bound(mp[x].begin(), mp[x].end(), r) - lower_bound(mp[x].begin(), mp[x].end(), l) << endl; }
三、完整代码
温馨提示:看最后面的代码。
#include <iostream> #include <map> #include <vector> #include <algorithm> using namespace std;int main() {int T;cin >> T;while (T--) {int n, q;map<int, vector<int> > mp;cin >> n;for (int i = 1; i <= n; i++) {int x;cin >> x;mp[x].push_back(i);}cin >> q;while (q--) {int l, r, x;cin >> l >> r >> x;cout << upper_bound(mp[x].begin(), mp[x].end(), r) - lower_bound(mp[x].begin(), mp[x].end(), l) << endl;}}return 0; }
居然超时
在这里,加上ios::sync...也没有AC,我们需要把cin, cout改成scanf, printf或快读快写。
#include <iostream> #include <map> #include <vector> #include <algorithm> using namespace std;map<int, vector<int> > mp;int main() {int T;scanf("%d", &T);while (T--) {mp.clear();int n, q;scanf("%d", &n);for (int i = 1; i <= n; i++) {int x;scanf("%d", &x);mp[x].push_back(i);}scanf("%d", &q);while (q--) {int l, r, x;scanf("%d%d%d", &l, &r, &x);printf("%d\n", upper_bound(mp[x].begin(), mp[x].end(), r) - lower_bound(mp[x].begin(), mp[x].end(), l));}}return 0; }
有错请大方指出谢谢!
有错别字请大方指出谢谢!