您的位置:首页 > 其它

HDU 5249 KPI

2015-12-07 20:52 134 查看
[align=left]Problem Description[/align]
你工作以后, KPI 就是你的全部了. 我开发了一个服务,取得了很大的知名度。数十亿的请求被推到一个大管道后同时服务从管头拉取请求。让我们来定义每个请求都有一个重要值。我的KPI是由当前管道内请求的重要值的中间值来计算。现在给你服务记录,有时我想知道当前管道内请求的重要值得中间值。
 

[align=left]Input[/align]
有大约100组数据。

每组数据第一行有一个n(1≤n≤10000),代表服务记录数。

接下来有n行,每一行有3种形式

  "in x": 代表重要值为x(0≤x≤109)的请求被推进管道。

  "out": 代表服务拉取了管道头部的请求。

  "query: 代表我想知道当前管道内请求重要值的中间值. 那就是说,如果当前管道内有m条请求, 我想知道,升序排序后第floor(m/2)+1th
条请求的重要值.

为了让题目简单,所有的x都不同,并且如果管道内没有值,就不会有"out"和"query"操作。

 

[align=left]Output[/align]
对于每组数据,先输出一行

Case #i:

然后每一次"query",输出当前管道内重要值的中间值。

 

[align=left]Sample Input[/align]

6
in 874
query
out
in 24622
in 12194
query

 

[align=left]Sample Output[/align]

Case #1:
874
24622

 

[align=left]Source[/align]
2015年百度之星程序设计大赛 - 初赛(1)

 

[align=left]Recommend[/align]
hujie   |   We have carefully selected several similar problems for you:  5594 5593 5589 5588 5587 
 

树状数组记录每个数的下标,弄个队列存先出去的下标,然后搞搞就可以了。
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <queue>
#include <stack>
using namespace std;
typedef long long ll;
const int maxn=10005;
int n;
int a[maxn];
int b[maxn];
int c[maxn];
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int v)
{
for(int i=x; i<=n; i+=lowbit(i))
c[i]+=v;
}
int sum(int x)
{
int s=0;
while(x>0)
{
s+=c[x];
x-=lowbit(x);
}
return s;
}
int find_kth(int k)//太神奇了(大概是以前没有完全领会),log(n)复杂度
{
int ans = 0, cnt = 0, i;
for (i = 20; i >= 0; i--)//利用二进制的思想,把答案用一个二进制数来表示
{
ans += (1 << i);
if (ans >= n|| cnt + c[ans] >= k)
//这里大于等于k的原因是可能大小为ans的数不在c[ans]的控制范围之内,所以这里求的是 < k
ans -= (1 << i);
else
cnt += c[ans];//cnt用来累加比当前ans小的总组数
}//求出的ans是累加和(即小于等于ans的数的个数)小于k的情况下ans的最大值,所以ans+1就是第k大的数
return a[ans + 1];
}
int main()
{
int icase=0;
while(scanf("%d",&n)!=EOF)
{
char s[10005][12];
int i;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
int len=1;
for(i=1; i<=n; i++)
{
cin>>s[i];
if(s[i][0]=='i')
{
int x;
scanf("%d",&x);
a[len++]=x;
b[i]=x;
}
}
sort(a+1,a+len+1);
int cnt=unique(a+1,a+len+1)-(a+1);
queue<int>q;
while(!q.empty())
q.pop();
printf("Case #%d:\n",++icase);
for(i=1; i<=n; i++)
{
if(s[i][0]=='i')
{
int x=lower_bound(a+1,a+cnt+1,b[i])-a;
update(x,1);
q.push(x);
}
else if(s[i][0]=='o')
{
int x=lower_bound(a+1,a+cnt+1,a[q.front()])-a;
update(x,-1);
q.pop();
}
else
{
//cout<<(q.size()/2+1)<<endl;
printf("%d\n",find_kth(q.size()/2+1));
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM算法