给定大小为N的数组arr []和由M个查询组成的数组Q [] [] ,需要在给定数组上进行处理。众所周知,这些查询可以是以下两种类型:
- 类型1:如果Q = 1,则在数组{type,element_to_add}中添加一个元素。
- 类型2:如果Q = 2,则打印数组中第K个最小的元素。 {type,k}
任务是执行给定的查询,以便给出以下约束:
- 1≤查询数≤1000000。
- 1≤N≤1000000。
- 1≤arr [i]≤100000000。并且,数组可以包含重复的条目。
例子:
Input: arr[] = {1, 2, 3, 4, 5, 6}, Q[][] = {{1, 7}, {2, 4}, {1, 5}, {2, 6}}
Output: 4 5
Explanation:
The first query is used to add 7 in the array. The array arr[] becomes: {1, 2, 3, 4, 5, 6, 7}
The second query is to find 4th smallest element. It is 4 in this case.
The third query is used to add 5 in the array. The array arr[] becomes: {1, 2, 3, 4, 5, 5, 6, 7}
The fourth query is to find 6th smallest element. It is 5 in this case.
Input: arr[] = {2, 4, 2, 1, 5, 6, 2, 4}, Q[][] = {{1, 3}, {2, 2}, {1, 10}, {2, 7}}
Output: 2 4
幼稚的方法:针对此问题的幼稚的方法是在数组中添加元素,并为每种第一种查询类型对数组进行排序。并且,无论何时发生第二种查询,都将在排序数组中打印第K个元素。
时间复杂度: O(M *(Nlog(N)))其中,M是查询数,N是数组的大小。
高效方法:想法是使用基于策略的数据结构。对于此问题,我们可以使用order_of_key数据结构来查找数组中第K个最小的元素。
- order_of_key()是有序集的内置函数,它是C++中基于策略的数据结构。基于策略的数据结构不是C++标准库的一部分,但g ++编译器支持它们。该数据结构找到对数时间复杂度的第K个最小元素。
- 但是,此数据结构不允许重复的键。为了将数据结构用于重复元素,使用了一对。
- 我们创建一对给定的元素和索引号,以将其插入基于策略的数据结构中。
- 首先通过将第一个元素与第二个元素进行比较来对这些对进行排序。例如,(2,1)在(2,7)之前排序。
下面是上述方法的实现:
// C++ program to find K-th
// smallest element in an array
// for multiple queries
#include
using namespace std;
#include
#include
using namespace __gnu_pbds;
template
// Defining the policy-based data
// structure
using oset
= tree, rb_tree_tag,
tree_order_statistics_node_update>;
// Function to find K-th
// smallest element in an array
// for multiple queries
void Operations(int arr[], int n,
int query[][2], int k)
{
// Declare the data structure that
// stores the pairs
oset > s;
int j = 0;
// Loop to insert the inital array
// elements into the set
for (j = 0; j < n; j++) {
s.insert({ arr[j], j });
}
// Loop to process the queries
for (int i = 0; i < k; i++) {
if (query[i][0] == 1) {
// Inserting the element if the
// type of query is 1
s.insert({ query[i][1], j });
j++;
}
// Finding the K-th smallest element
// if the type of the query is 2
else if (query[i][0] == 2) {
cout << (*s
.find_by_order(
query[i][1] - 1))
.first
<< endl;
}
}
}
// Driver code
int main()
{
int n = 8;
int arr[] = { 2, 4, 2, 1, 5, 6, 2, 4 };
int k = 4;
// Queries. The first element denotes
// the type of the query
int query[4][2] = { { 1, 3 },
{ 2, 2 },
{ 1, 10 },
{ 2, 7 } };
Operations(arr, n, query, k);
return 0;
}
2
4
时间复杂度: O(M * log(N)) ,其中M是查询数,N是数组的大小。
如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。