思路:

首先对于单个查询(k, p)来说,答案一定是a数组中的前k大数。如果第k大的数字有多个怎么办?取索引最小的若干个。所以我们只需对a数组按照值降序,索引升序排序即可。

多个查询怎么办?离线处理。依然是对数组a按照上面的方法排序,然后对所有的查询按照k升序排序,分别离线计算。具体做法是,按顺序扫描a,用一个集合动态维护前k大的数,当发现某个查询正好询问前k大时,即时处理即可。

那么如何从一个集合中快速找到第k大数?c++标准库中原始的set是不行的,可以用1. 二分+树状数组(或线段树)2. __gnu_pbds https://www.geeksforgeeks.org/ordered-set-gnu-c-pbds/

实现1(二分+树状数组,n * log(n) * log(n)):

 1 #include <bits/stdc++.h>
 2  
 3 using namespace std;
 4 const int MAXN = 200000;
 5 typedef pair<int, int> pii;
 6  
 7 int a[MAXN + 5], bit[MAXN + 5];
 8  
 9 int lowbit(int x) { return x & -x; }
10  
11 void add(int i, int x)
12 {
13     while (i <= MAXN) { bit[i] += x; i += lowbit(i); }
14 }
15  
16 int sum(int i)
17 {
18     int ans = 0;
19     while (i) { ans += bit[i]; i -= lowbit(i); }
20     return ans;
21 }
22  
23 bool cmp(pii& a, pii& b)
24 {
25     if (a.first != b.first) return a.first > b.first;
26     return a.second < b.second; 
27 }
28  
29 void work(pii& q, map<pii, int>& mp)
30 {
31     int k = q.first, p = q.second;
32     int l = 1, r = MAXN, res = -1;
33     while (l <= r)
34     {
35         int m = l + r >> 1;
36         if (sum(m) < p) l = m + 1;
37         else { res = m; r = m - 1; }
38     }
39     assert(res != -1);
40     mp[q] = res;
41 }
42  
43 int main()
44 {
45     ios::sync_with_stdio(false);
46     int n, m;
47     while (cin >> n)
48     {
49         memset(bit, 0, sizeof bit);
50         vector<int> a(n);
51         for (int i = 0; i < n; i++) cin >> a[i];
52         vector<pii> b(n);
53         for (int i = 0; i < n; i++) { b[i].first = a[i]; b[i].second = i + 1; }
54         sort(b.begin(), b.end(), cmp);
55         cin >> m;
56         vector<pii> q(m);
57         for (int i = 0; i < m; i++) cin >> q[i].first >> q[i].second;
58         vector<pii> sorted_q(q.begin(), q.end());
59         sort(sorted_q.begin(), sorted_q.end());
60         map<pii, int> res;
61         int cur = 0;
62         for (int i = 0; i < n; i++)
63         {
64             add(b[i].second, 1);
65             while (cur < m && i + 1 == sorted_q[cur].first)
66             {
67                 work(sorted_q[cur], res);
68                 cur++;
69             }
70         }
71         for (auto it: q)
72         {
73             int id = res[it];
74             cout << a[id - 1] << endl;
75         }
76     }
77     return 0;
78 }

实现2(__gnu_pbds,n * log(n)):

 1 #include <bits/stdc++.h>
 2  
 3 #include <ext/pb_ds/assoc_container.hpp>
 4 #include <ext/pb_ds/tree_policy.hpp>
 5  
 6 using namespace std;
 7 using namespace __gnu_pbds;
 8  
 9 typedef pair<int, int> pii;
10 typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
11  
12 bool cmp(pii& a, pii& b)
13 {
14     if (a.first != b.first) return a.first > b.first;
15     return a.second < b.second; 
16 }
17  
18 int main()
19 {
20     ios::sync_with_stdio(false);
21     int n, m;
22     while (cin >> n)
23     {
24         vector<int> a(n);
25         for (int i = 0; i < n; i++) cin >> a[i];
26         vector<pii> b(n);
27         for (int i = 0; i < n; i++) { b[i].first = a[i]; b[i].second = i + 1; }
28         sort(b.begin(), b.end(), cmp);
29         cin >> m;
30         vector<pii> q(m);
31         for (int i = 0; i < m; i++) cin >> q[i].first >> q[i].second;
32         vector<pii> sorted_q(q.begin(), q.end());
33         sort(sorted_q.begin(), sorted_q.end());
34         map<pii, int> res;
35         int cur = 0;
36         ordered_set st;
37         for (int i = 0; i < n; i++)
38         {
39             st.insert(b[i].second);
40             while (cur < m && i + 1 == sorted_q[cur].first)
41             {
42                 res[sorted_q[cur]] = *st.find_by_order(sorted_q[cur].second - 1);
43                 cur++;
44             }
45         }
46         for (auto it: q)
47         {
48             cout << a[res[it] - 1] << endl;
49         }
50     }
51 }

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-07-01
  • 2022-01-18
  • 2022-02-12
  • 2021-07-06
  • 2021-05-21
猜你喜欢
  • 2022-02-15
  • 2021-10-14
  • 2021-10-26
  • 2021-07-06
相关资源
相似解决方案