当前位置:   article > 正文

模拟队列维护最大最小值_实时维护数列最大值最小值的方法

实时维护数列最大值最小值的方法

                                        队列极值

问题描述

转眼间【HuJie】在灵隐寺待了将近半年,别说和日剧里的和尚似的泡到妹子结婚,就是连妹子的人影都见不着。好歹我们【HuJie】也是一表人才,英俊潇洒的,怎么能孤独终老呢?他才明白日剧里都是骗人的,还是回去好好的念书吧。但是,【HuJie】偷偷出家的日子里已经旷了不少课了,所幸没有被学校查课给查出来,于是又偷偷溜回来上课了。但是实验室的【潘老师】可不会这么容易就放过贪玩的【HuJie】,他因为实验室的事情忙得不行,却到处找不着【HuJie】,这回【HuJie】自己溜回来了。于是【潘老师】对【HuJie】说:“这样吧,你做一道《数据结构》的队列题,要是做出来了,我就不追究你了。不过这次的数据量有点儿大,可要好好想想怎么做。”聪明的你能帮帮他吗?

输入描述

输入包含多组数据,每组数据以一个正整数n(1≤n≤5×〖10〗^5)开始,表示之后共有n次队列操作,之后n行每行包含一个操作。入队操作为”ENQUEUE x”,其中0≤x≤〖10〗^9表示将元素x入队;出队操作为”DEQUEUE”;询问操作为”MAX”或”MIN”,分别表示询问当前队列中的最大值或最小值。输入数据以0结束。

输出描述

对应每一组输入数据,第一行输出”Case #:”表示第#组数据,之后对每一次出队操作返回当前出队的元素,对每一次询问操作输出恰当的结果,若队列为空则输出”EMPTY!”,每次输出占一行。

样例输入

  1. 3
  2. ENQUEUE 1
  3. MAX
  4. DEQUEUE
  5. 5
  6. ENQUEUE 2
  7. MAX
  8. DEQUEUE
  9. MIN
  10. DEQUEUE
  11. 0

样例输出

  1. Case 1:
  2. 1
  3. 1
  4. Case 2:
  5. 2
  6. 2
  7. EMPTY!
  8. EMPTY!

分析:

维护最大值的队列:
每插入一个元素时,就要与队尾的元素比较,如果插入的元素比队尾的元素大,就删除现在队尾的元素,下一个队尾的元素比较,如果还比队尾大,再删除,再与新的队尾元素比较,如此循环往复,知道队列为空,或者队尾的元素要大于或等于插入的元素,就将新元素插入队列尾部。这个队列就是一个从队首至队尾 永远单调递减的序列,队首即为max值
最小值队列就是反着来 维护一个 队首至队尾 永远单调递增的序列,队首即为min值
队列中的数据除了要储存它的值还要为其分配一个编号,要出队的元素是否就是max队列和min队列队首的元素的,看其编号即可,所以用数组来建队,数组的编号作为队中数据的标记。

三个数组:max数组-单调递减,min数组-单调递增,所有数普通数组。

  1. #include<cstdio>
  2. #include<cstring>
  3. #define maxn 600010
  4. char a[10];
  5. int queue[maxn];
  6. int maxqueue[maxn];
  7. int minqueue[maxn];
  8. int q1,maq1,miq1;
  9. int q2,maq2,miq2;
  10. void init(){
  11. q1 = 1,maq1 = 1,miq1 = 1;
  12. q2 = 1,maq2 = 1,miq2 = 1;
  13. }
  14. void push(int x){
  15. queue[q1++] = x;
  16. while(maxqueue[maq1-1] < x&&maq1 > maq2){
  17. maq1--;
  18. }
  19. maxqueue[maq1++] = x;
  20. while(minqueue[miq1-1] > x&&miq1 > miq2){
  21. miq1--;
  22. }
  23. minqueue[miq1++] = x;
  24. return ;
  25. }
  26. void pop(){
  27. if(q1<=q2){printf("EMPTY!\n"); return;}
  28. int ans = queue[q2++];
  29. printf("%d\n",ans);
  30. if(maxqueue[maq2] == ans) maq2++;
  31. if(minqueue[miq2] == ans) miq2++;
  32. return ;
  33. }
  34. void MIN(){
  35. if(miq2==miq1){printf("EMPTY!\n");return;}
  36. printf("%d\n",minqueue[miq2]);
  37. return;
  38. }
  39. void MAX(){
  40. if(maq2==maq1){printf("EMPTY!\n");return;}
  41. printf("%d\n",maxqueue[maq2]);
  42. return;
  43. }
  44. int main(){
  45. int t,i = 1;
  46. while(~scanf("%d",&t)&&t){
  47. init();
  48. printf("Case %d:\n",i++);
  49. while(t--){
  50. memset(a,0,sizeof(a));
  51. scanf("%s",a);
  52. int x;
  53. if(a[0] == 'E'){
  54. scanf("%d",&x);
  55. push(x);
  56. }else if(a[0] == 'D'){
  57. pop();
  58. }else if(a[1] == 'A'){
  59. MAX();
  60. }else{
  61. MIN();
  62. }
  63. }
  64. }
  65. return 0;
  66. }
'
运行

 

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/960711
推荐阅读
相关标签
  

闽ICP备14008679号