📜  查找通过对空数组执行 Q 查询形成的数组

📅  最后修改于: 2022-05-13 01:56:07.553000             🧑  作者: Mango

查找通过对空数组执行 Q 查询形成的数组

考虑一个整数序列S ,它最初是空的(即 S = {})。还给出了Q查询,每个查询都是以下类型之一:

  • 1 ab:将ab插入序列S。
  • 2 ab:在序列S中,在小于等于a的元素中,打印第b大的元素。如果不存在这样的元素,则打印 -1。
  • 3 ab:在序列S中,在大于等于a的元素中,打印第b个最小的元素。如果不存在这样的元素,则打印 -1

任务是打印执行所有 Q 查询后形成的最终序列。

例子:

方法:这个问题可以使用二分搜索和多重集来解决。

  • 将序列初始化为多重集(例如 s)。
  • 遍历向量 A 以处理查询。
  • 如果查询是类型 1,则将ab都插入到多重集中。
  • 如果查询是类型 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)