8 3 I 1 I 2 I 3 Q I 5 Q I 4 Q
1 2 3HintXiao 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).
这道可以直接就用STL的优先队列水过,最近要熟悉stl里面的操作和用法,用这些题练练手,还是不错的,这道题要注意的是用stl的优先队列时,元素的比较规则默认是按元素值的大小从大到小排序;这道题用优先队列来做的话,直接是维护一个k长度的优先队列,要把元素值大小从小到大排序,它的第k大的值就是队首元素,所以每次的查询就输出队首元素就行了;这里就需要重载操作符来实现它的排序;
下面是用stl写的代码;
#include <cstdio> #include <queue> using namespace std; int main() { int n,k,m; char s[5]; while(scanf("%d%d",&n,&k)!=EOF) { priority_queue<int, vector<int>, greater<int> > q;//这里就是对优先队列进行排序 for(int i=0;i<n;i++) { scanf("%s",s); if(s[0]=='I') { scanf("%d",&m); if(q.size()<k) q.push(m);//入队 else if(m>q.top()) { q.pop();//出队 q.push(m); } } else { printf("%d\n",q.top());//输出 } } } return 0; }
#include <stdio.h> #include <string.h> #define MAX 1000010 int n,m; struct SBT {//结构体 int left,right,size,key; void Init() { left = right = 0; size = 1; } }a[MAX]; int tot,root; void left_rotate(int &t) {//左旋转 int k = a[t].right; a[t].right = a[k].left; a[k].left = t; a[k].size = a[t].size; a[t].size = a[a[t].left].size + a[a[t].right].size + 1; t = k; } void right_rotate(int &t) {//右旋转 int k = a[t].left; a[t].left = a[k].right; a[k].right = t; a[k].size = a[t].size; a[t].size = a[a[t].left].size + a[a[t].right].size + 1; t = k; } void maintain(int &t,int flag) {//维护 if (flag == 0) { if (a[a[a[t].left].left].size > a[a[t].right].size) right_rotate(t); else if (a[a[a[t].left].right].size > a[a[t].right].size) left_rotate(a[t].left),right_rotate(t); else return; } else { if (a[a[a[t].right].right].size > a[a[t].left].size) left_rotate(t); else if (a[a[a[t].right].left].size > a[a[t].left].size) right_rotate(a[t].right),left_rotate(t); else return; } maintain(a[t].left,0); maintain(a[t].right,1); maintain(t,0); maintain(t,1); } void insert(int &t,int v) {//插入 if (t == 0) t = ++tot,a[t].Init(),a[t].key = v; else { a[t].size++; if (v < a[t].key) insert(a[t].left,v); else insert(a[t].right,v); maintain(t,v>=a[t].key); } } int del(int &t,int v) {//删除 if (!t) return 0; a[t].size--; if (v == a[t].key || v < a[t].key && !a[t].left || v > a[t].key && !a[t].right) { if (a[t].left && a[t].right) { int p = del(a[t].left,v+1); a[t].key = a[p].key; return p; } else { int p = t; t = a[t].left + a[t].right; return p; } } else return del(v<a[t].key?a[t].left:a[t].right,v); } int find(int t,int k) {//查找 if (k <= a[a[t].left].size) return find(a[t].left,k); if (k > a[a[t].left].size + 1) return find(a[t].right,k-a[a[t].left].size-1); return a[t].key; } int main() { int i,j,k; while (scanf("%d%d",&n,&m) != EOF) { tot = root = 0; char ope[10]; while (n--) { scanf("%s",ope); if (ope[0] == 'I') { scanf("%d",&k); insert(root,k); } else printf("%d\n",find(root,a[root].size+1-m)); } } }http://www.nocow.cn/index.php/Size_Balanced_Tree这里面SBT讲的还不错,自己还是要多看几遍,还没完全弄懂
#include<cstdio> #include<cstring> #include<iostream> using namespace std; #define MAXN 1001000 #define lson l,m,root<<1 #define rson m+1,r,root<<1|1 int n,k; int node[MAXN<<2]; void push_up(int root) { node[root]=node[root<<1]+node[root<<1|1]; } void build(int l,int r,int root) { if(l==r) { node[root]=0; return ; } int m=(l+r)>>1; build(lson); build(rson); push_up(root); } void update(int n,int l,int r,int root) { if(l==r) { node[root]++; return ; } int m=(l+r)>>1; if(n<=m) update(n,lson); else update(n,rson); push_up(root); } int query(int p,int l,int r,int root) { if(l==r) { return l; } int m=(l+r)>>1; int ret; if(p<=node[root<<1]) ret=query(p,lson); else ret=query(p-node[root<<1],rson); return ret; } void solve() { char a[5]; int ff; build(1,MAXN,1); int counts=0; for(int i=1;i<=n;i++) { scanf("%s",a); if(a[0]=='I') { scanf("%d",&ff); update(ff,1,MAXN,1); counts++; } else printf("%d\n",query(counts-k+1,1,MAXN,1)); } } int main() { while(scanf("%d%d",&n,&k)!=EOF) solve(); return 0; }
#include <cstdio> #include <cstring> #include<iostream> using namespace std; int heap[1000010],size; void down(int r)//往下交换 { while(r<size) { int son=r*2; if(son+1<=size) son=heap[son]>heap[son+1]?son+1:son; if(son<=size && heap[r]>heap[son]) swap(heap[r],heap[son]); else return; r=son; } } void up(int r)//往上交换,查询 { while(r!=1) { if(heap[r]<heap[r/2]) swap(heap[r],heap[r/2]); else break; r>>=1; } } void heap_push(int k)//入队 { heap[++size]=k; up(size); } void heap_pop()//出队 { heap[1]=heap[size--]; down(1); } int main() { int n,k,m; char s[5]; while(scanf("%d%d",&n,&k)!=EOF) { size=0; for(int i=0;i<n;i++) { scanf("%s",s); if(s[0]=='I') { scanf("%d",&m); heap_push(m); if(size>k) heap_pop(); } else { printf("%d\n",heap[1]); } } } return 0; }用堆来模拟优先队列。
hdu 4006 The kth great number (优先队列+STB+最小堆),布布扣,bubuko.com
hdu 4006 The kth great number (优先队列+STB+最小堆)
原文地址:http://blog.csdn.net/whjkm/article/details/38436681