查找通过对空数组执行 Q 查询形成的数组
考虑一个整数序列S ,它最初是空的(即 S = {})。还给出了Q查询,每个查询都是以下类型之一:
- 1 ab:将a和b插入序列S。
- 2 ab:在序列S中,在小于等于a的元素中,打印第b大的元素。如果不存在这样的元素,则打印 -1。
- 3 ab:在序列S中,在大于等于a的元素中,打印第b个最小的元素。如果不存在这样的元素,则打印 -1
任务是打印执行所有 Q 查询后形成的最终序列。
例子:
Input: Q = 7, A = {{1, {20, 10}}, {1, {30, 20}}, {3, {15, 1}}, {3, {15, 2}}, {3, {15, 3}}, {3, {15, 4}}, {2, {100, 5}} }
Output: 20, 20, 30, -1, -1
Explanation: Initially sequence S={}.
=> After execution of initial 2 queries, it becomes: {20, 10, 30, 20}.
=> In the sequence, elements greater than 15 are 20, 20 and 30. In 3rd query, we have to print the 1st smallest number greater than or equal to 15 which is 20.
=> Similarly, 2nd and 3rd smallest integer which are greater than 15 are 20 and 30 respectively. Now, 6th query asks us the 4th smallest integer which is greater than or equal to 15. But, there are only 3 integers greater than 15, so we print -1. => The last Query asks us the 5th largest integer in the integers less than or equal to 100. But, there are only 4 integers (10, 20, 20, 30), which are less than or equal to 100. So, we print -1.
Input: Q = 6, A = {{1, {5, 7}}, {1, {2, 15}}, {1, {11, 16}}, {3, {14, 2}}, {2, {11, 3}}, {2, {10, 10}} }
Output: 16, 5, -1
方法:这个问题可以使用二分搜索和多重集来解决。
- 将序列初始化为多重集(例如 s)。
- 遍历向量 A 以处理查询。
- 如果查询是类型 1,则将a和b都插入到多重集中。
- 如果查询是类型 2,我们计算 s 中a的下限,并从该下限减少b次以获得小于或等于 a 的第b个最大元素。
- 如果查询是类型 3,我们计算 s 中a的上限,并从该上限增加b次,以获得大于或等于 a 的第b个最小元素。
- 在类型 2 或 3 的查询中,如果迭代器超出 s.begin() 或 s.end(),则将该查询的答案打印为 -1。否则,打印通过以上两步得到的答案。
以下是基于上述方法的代码:
C++
// C++ code for Find the sequence after
// performing Q queries
#include
using namespace std;
// function to perform the given queries on s
void solveQueries(int Q,
vector > >& A)
{
// initializing variable to store answer
// to current query and a multiset of integers
int ans;
multiset s;
// iterating through all queries
for (int i = 0; i < Q; i++) {
int t, a, b;
t = A[i].first;
a = A[i].second.first;
b = A[i].second.second;
// if query is of 1st type, we simply
// insert both a and b into our sequence
if (t == 1) {
s.insert(a);
s.insert(b);
continue;
}
// If query is of the second type, we
// calculate the lower bound of a
// and from that lower bound we decrement
// b times to get the bth largest element
// less than or equal to a
if (t == 2) {
ans = 0;
auto it = s.upper_bound(a);
for (int j = 0; j < b; j++) {
if (it == s.begin()) {
ans = -1;
break;
}
it--;
ans = *it;
}
}
// If query is of the third type,
// we calculate the upper bound of a and
// from that upper bound we increment b times
// to get the bth smallest element greater
// than or equal to a
else {
ans = 0;
auto it = s.lower_bound(a);
for (int j = 0; j < b; j++) {
if (it == s.end()) {
ans = -1;
break;
}
ans = *it;
it++;
}
}
// printing the answer
cout << ans << " ";
}
}
// Driver Code
int main()
{
int Q = 7;
vector > > A
= { { 1, { 20, 10 } }, { 1, { 30, 20 } }, { 3, { 15, 1 } }, { 3, { 15, 2 } }, { 3, { 15, 3 } }, { 3, { 15, 4 } }, { 2, { 100, 5 } } };
solveQueries(Q, A);
}
20 20 30 -1 -1
时间复杂度: O(Q*log(Q)),其中 Q 是查询次数
辅助空间: O(Q)