C/C++函数,比较两个字符串
设这两个字符串为str1,str2,
若str1=str2,则返回零;
若str1
头文件:string.h
维护一个集合,初始时集合为空,支持如下几种操作:
I x,插入一个数 x;
PM,输出当前集合中的最小值;
DM,删除当前集合中的最小值(数据保证此时的最小值唯一);
D k,删除第 k 个插入的数;
C k x,修改第 k 个插入的数,将其变为 x;
现在要进行 N 次操作,对于所有第 2 个操作,输出当前集合的最小值。
输入格式
第一行包含整数 N。
接下来 N 行,每行包含一个操作指令,操作指令为 I x,PM,DM,D k 或 C k x 中的一种。
数据范围
1≤N≤1e5
−1e9≤x≤1e9
const int N=100010; int h[N], ph[N], hp[N], cnt; 这里的cnt指的是下标到第几个位置了 h数组用来存储插入的值如何理解hp和ph数组
首先需要理解的是hp和ph这两个数组到底存的是啥,到底有啥作用,如果不建立这两个数组为什么不行?
hp是heap pointer的缩写,表示堆数组中下标到第k个插入的映射
ph是pointer heap的缩写,表示第k个插入到堆数组中的下标的映射
hp和ph数组是互为反函数的
在堆这个数据结构中,数据的插入都是插入到堆尾,然后再up的。
//代码如下
if (!strcmp(op, "I"))
{
scanf("%d", &x);
cnt ++ ;
m ++ ;//记录第几次插入
ph[m] = cnt, hp[cnt] = m;//每次插入都是在堆尾插入
h[cnt] = x;//记录插入的值
up(cnt);
}
这里暂时没有体现出hp和ph的作用
删除集合中的最小值先将第一个元素与最后一个元素进行位置互换,然后删除最后一个元素,再将第一个元素down下去
if (!strcmp(op, "DM"))
{
heap_swap(1, cnt);
cnt -- ;
down(1);
在删除第k个插入元素的操作中,我们首先得知道第k个插入元素在堆数组中的什么位置,即堆数组下标是啥。
很显然,用一个ph数组来存储会方便查找。这样我们就知道了第k个插入的元素在哪了。然后我们需要做的是和堆尾元素交换,最后再在原来第k个元素所在的位置进行down和up操作。
由于交换完后ph[k]的值变了,为ph[cnt]了,所以必须要在之前保存ph[k]的值,不然无法进行down和up操作。
if (!strcmp(op, "D"))
{
scanf("%d", &k);
k = ph[k];
heap_swap(k, cnt);
cnt -- ;
up(k);
down(k);
}
修改第k个插入的数
if(!strcmp(op, "C")){
scanf("%d%d", &k, &x);
k = ph[k];
h[k] = x;
up(k);
down(k);
}
似乎有了ph数组就可以完成所有操作了,但为什么还要有一个hp数组呢?
原因就在于在swap操作中我们输入是堆数组的下标,无法知道每个堆数组的下标对应的是第几个插入的元素。
所以需要hp数组方便查找
明白了这些也不难理解heap_swap函数啦
void heap_swap(int a, int b)
{
swap(ph[hp[a]],ph[hp[b]]);
swap(hp[a], hp[b]);
swap(h[a], h[b]);
}
完整代码
#include#include #include using namespace std; const int N = 100010; int h[N], ph[N], hp[N], cnt; void heap_swap(int a, int b) { swap(ph[hp[a]],ph[hp[b]]); swap(hp[a], hp[b]); swap(h[a], h[b]); } void down(int u) { int t = u; if (u * 2 <= cnt && h[u * 2] < h[t]) t = u * 2; if (u * 2 + 1 <= cnt && h[u * 2 + 1] < h[t]) t = u * 2 + 1; if (u != t) { heap_swap(u, t); down(t); } } void up(int u) { while (u / 2 && h[u] < h[u / 2]) { heap_swap(u, u / 2); u >>= 1; } } int main() { int n, m = 0; scanf("%d", &n); while (n -- ) { char op[5]; int k, x; scanf("%s", op); if (!strcmp(op, "I")) { scanf("%d", &x); cnt ++ ; m ++ ; ph[m] = cnt, hp[cnt] = m; h[cnt] = x; up(cnt); } else if (!strcmp(op, "PM")) printf("%dn", h[1]); else if (!strcmp(op, "DM")) { heap_swap(1, cnt); cnt -- ; down(1); } else if (!strcmp(op, "D")) { scanf("%d", &k); k = ph[k]; heap_swap(k, cnt); cnt -- ; up(k); down(k); } else { scanf("%d%d", &k, &x); k = ph[k]; h[k] = x; up(k); down(k); } } return 0; }



