分块思想(参考算法笔记):
假设数组大小为N,那么我们把数组分成 block_num = sqrt(N)个块【向上取整】,每个块的范围是 block_size = sqrt(N)【向下取整】,用 block[i]记录第 i 块的元素个数 ,然后再开一个数组 table[i] 记录数值为 i 的元素个数
添加元素 x 的时候,计算元素对应的块号为idx = x / block_size ,然后令 block[idx]+=1 , table[x] +=1
删除元素 x 的时候,计算元素对应的块号为idx = x / block_size,然后令 block[idx] -=1 , table[x] -=1
查询第 k 个元素的时候,
首先在块间搜索,遍历block数组,统计元素的个数,这里我们用sum统计个数,如果sum + block[idx] >= K,说明第 k 个元素在第 idx 块。
这个时候我们进入块内搜索,计算块的开始地址:begin = idx * block_size,end = begin + block_size ,我们取 遍历 table[ begin , end ) ,如果sum + table[i] >= K ,说明 i 就是第 k 个元素
#define maxn 100001
#define sqrN 316
int block[maxn], table[maxn];
void push(int x) {
int idx = x / sqrN;
block[idx]++;
cnt[x]++;
}
bool pop(int x) {
int idx = x / sqrN;
if (block[idx] == 0)return false;
block[idx]--;
cnt[x]--;
return true;
}
int getKth(int K) {
int sum = 0;
int idx = 0;
while (sum + block[idx] < K) {
sum += block[idx++];
}
int num = idx*sqrN;
while (sum + table[num] < K) {
sum += table[num++];
}
return num;
}