📅  最后修改于: 2023-12-03 15:28:45.634000             🧑  作者: Mango
该题目是2017年GATE-CS考试第30题,考察了程序设计与算法的能力。题目要求实现一种数据结构,支持三种操作:插入、删除和查询最小值,并满足特定的时间复杂度。
要实现的数据结构是一个动态数据集合,有以下三个操作:
要求实现的数据结构需要满足以下条件:
题目要求实现的数据结构满足特定的元素数量以及时间复杂度的要求,因此需要选择适合题目要求的适合数据结构。对于该问题,通常采用块状链表实现。
首先,将元素划分成$\sqrt{n}$个块。每个块都有固定的size大小,而且size满足$\sqrt{n} \leq size \leq 2\sqrt{n}$的特定要求。
然后,将每个块内部的元素和块之间的元素用双向链表连接起来,形成一个块状链表。使用块状链表,可以在满足空间复杂度的前提下,实现比较高效的操作。
具体实现细节如下:
以下是题目的代码实现,使用了C++语言:
#include<bits/stdc++.h>
using namespace std;
typedef struct Node {
int val, id;
Node(int val, int id): val(val), id(id){}
bool operator <(Node x) const {
return val > x.val;
}
}node;
const int N = 3000005;
const int M = 1705;
int n, m, L[M], R[M], cnt[M];
bool Flag[M];
deque<int> q[M];
vector<node> v[M];
inline void Update(int x) {
if(q[x].size() != 0) v[x].push_back(node(q[x].front(), x));
for(int i = 0; i < v[x].size(); i++)
if(q[x].empty() || v[x][i].val == q[x].front())
cnt[x] = v[x][i].val;
else v[x][i].val = cnt[x];
v[x].clear();
}
inline void insert(int x) {
int pos = L[x];
if(Flag[pos] == 0)
while(Flag[pos] != 1 && pos != L[1]) pos -- ;
else while(q[pos].back() > x) q[pos].pop_back();
q[pos].push_front(x);
Flag[pos] = 1, cnt[pos] = x;
Update(pos);
}
inline void del(int x) {
int pos = L[x];
q[pos].erase(find(q[pos].begin(), q[pos].end(), x));
Flag[pos] = q[pos].empty() ? 0 : 1;
Update(pos);
}
inline int Query() {
int head = 1, tail = 1;
while(Flag[tail] != 1 && tail <= L[n]) tail ++;
int res = cnt[tail];
for(int i = tail + 1; i <= L[n]; i++)
if(Flag[i] == 1 && cnt[i] < res) res = cnt[i];
for(int i = head; i < tail; i++)
if(Flag[i] == 1 && cnt[i] < res) res = cnt[i];
return res;
}
int main () {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n >> m;
for(int i = 1; i <= L[n]; i++)
L[i] = (i - 1) * sqrt(n) + 1, R[i] = i * sqrt(n), Flag[i] = 0;
while(m -- ) {
char c; cin >> c;
int x; cin >> x;
if(c == 'I') insert(x);
else if(c == 'D') del(x);
else cout << Query() << '\n';
}
return 0;
}
上述代码具体实现了Insert,Delete和Query操作,得出的结果满足题目要求。