标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)
8 3 I 1 I 2 I 3 Q I 5 Q I 4 Q
【Sample Output】
1 2 3
【Hint】
Xiao Ming won‘t ask Xiao Bao the kth great number when the number of the written number is smaller than k. (1=<k<=n<=1000000).
【题意】
给出一系列操作:
1.记录一个数;2.求第k小的数
【分析】
解法一、
题目每次询问的只是其中的一个数,这种情况下用一个堆来维护所有数的集合即可。
而且本题的k是一个固定值,因此只需要一个小根堆即可;若k不是一个固定值,则需要一个小根堆配合大根堆共同完成。
堆可以用STL中的优先队列来代替。
创建一个小根堆并向其加入数据,若堆中的数量大于k则弹出堆顶元素,始终保持整个堆中只有k个元素。遇到询问时,读取堆顶元素。
1 /* *********************************************** 2 MYID : Chen Fan 3 LANG : G++ 4 PROG : HDU4006 5 ************************************************ */ 6 7 #include <iostream> 8 #include <cstdio> 9 #include <cstring> 10 #include <algorithm> 11 #include <queue> 12 13 using namespace std; 14 15 struct cmp 16 { 17 bool operator()(int x,int y) 18 { 19 return x>y; 20 } 21 }; 22 23 int main() 24 { 25 //freopen("1.txt","r",stdin); 26 //freopen("std.txt","w",stdout); 27 28 int n,k; 29 30 while(scanf("%d%d",&n,&k)==2) 31 { 32 priority_queue<int,vector<int>,cmp>q; 33 char c; 34 for (int i=1;i<=n;i++) 35 { 36 c=getchar(); 37 while(c!=‘I‘&&c!=‘Q‘) 38 { 39 c=getchar(); 40 } 41 if (c==‘I‘) 42 { 43 int now; 44 scanf("%d",&now); 45 q.push(now); 46 if (q.size()>k) q.pop(); 47 } else 48 { 49 printf("%d\n",q.top()); 50 } 51 } 52 } 53 54 return 0; 55 }
解法二、
本题可作为平衡树模板题,虽然因为有点大材小用内存占用比较大,而且时间上并没有太大优势。
动态维护一棵平衡树,求k大值。
以下采用Size Balanced Tree完成:
1 /* *********************************************** 2 MYID : Chen Fan 3 LANG : G++ 4 PROG : HDU4006_SBT 5 ************************************************ */ 6 7 #include <iostream> 8 #include <cstdio> 9 #include <cstring> 10 #include <algorithm> 11 12 using namespace std; 13 14 #define MAXN 1000010 15 16 typedef struct sbtnod 17 { 18 int key,left,right,size; 19 } sbtnode; 20 int sbttail,sbt; 21 22 sbtnode tree[MAXN]; 23 24 void rrotate(int& t) 25 { 26 int k=tree[t].left; 27 if (!k) return ; 28 tree[t].left=tree[k].right; 29 tree[k].right=t; 30 tree[k].size=tree[t].size; 31 tree[t].size=tree[tree[t].left].size+tree[tree[t].right].size+1; 32 t=k; 33 } 34 35 void lrotate(int& t) 36 { 37 int k=tree[t].right; 38 if (!k) return ; 39 tree[t].right=tree[k].left; 40 tree[k].left=t; 41 tree[k].size=tree[t].size; 42 tree[t].size=tree[tree[t].left].size+tree[tree[t].right].size+1; 43 t=k; 44 } 45 46 void maintain(int& t,bool flag) 47 { 48 if (!t) return ; 49 if (!flag) 50 if (tree[tree[tree[t].left].left].size>tree[tree[t].right].size) rrotate(t); 51 else if (tree[tree[tree[t].left].right].size>tree[tree[t].right].size) 52 { 53 lrotate(tree[t].left); 54 rrotate(t); 55 } else return ; 56 else 57 if (tree[tree[tree[t].right].right].size>tree[tree[t].left].size) lrotate(t); 58 else if (tree[tree[tree[t].right].left].size>tree[tree[t].left].size) 59 { 60 rrotate(tree[t].right); 61 lrotate(t); 62 } else return ; 63 64 maintain(tree[t].left,false); 65 maintain(tree[t].right,true); 66 maintain(t,false); 67 maintain(t,true); 68 } 69 70 void insert(int& t,int v) 71 { 72 if (!t) 73 { 74 sbttail++; 75 tree[sbttail].key=v; 76 tree[sbttail].size=1; 77 t=sbttail; 78 } else 79 { 80 tree[t].size++; 81 if (v<tree[t].key) insert(tree[t].left,v); 82 else insert(tree[t].right,v); 83 maintain(t,v>=tree[t].key); 84 } 85 } 86 87 int del(int& t,int v) 88 { 89 int ret; 90 tree[t].size--; 91 if (v==tree[t].key||(v<tree[t].key&&tree[t].left==0)||(v>tree[t].key&&tree[t].right==0)) 92 { 93 ret=tree[t].key; 94 if (tree[t].left==0||tree[t].right==0) t=tree[t].left+tree[t].right;// 95 else tree[t].key=del(tree[t].left,tree[t].key+1); 96 } else 97 { 98 if (v<tree[t].key) ret=del(tree[t].left,v); 99 else ret=del(tree[t].right,v); 100 } 101 return ret; 102 } 103 104 int select(int t,int k) 105 { 106 if (k==tree[tree[t].left].size+1) return t; 107 if (k<=tree[tree[t].left].size) return select(tree[t].left,k); 108 else return select(tree[t].right,k-1-tree[tree[t].left].size); 109 } 110 111 int main() 112 { 113 //freopen("1.txt","r",stdin); 114 //freopen("st.txt","w",stdout); 115 116 int n,k; 117 while(scanf("%d%d",&n,&k)==2) 118 { 119 memset(tree,0,sizeof(tree)); 120 sbttail=0; 121 sbt=0; 122 123 char c; 124 for (int i=1;i<=n;i++) 125 { 126 c=getchar(); 127 while(c!=‘I‘&&c!=‘Q‘) 128 { 129 c=getchar(); 130 } 131 int now; 132 if (c==‘I‘) 133 { 134 scanf("%d",&now); 135 insert(sbt,now); 136 } else 137 { 138 now=select(sbt,sbttail-k+1); 139 printf("%d\n",tree[now].key); 140 } 141 } 142 } 143 144 return 0; 145 }
HDU The kth great number 优先队列、平衡树模板题(SBT)
标签:
原文地址:http://www.cnblogs.com/jcf94/p/4322222.html