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