题意
给定一个
n
n
,操作数。接下来会有插入管道(队列),移除管道头,求此时中位数这三种操作,完成这些操作。
1≤n≤10000
1
≤
n
≤
10000
思路
此题需要维护队头、入队、求中位数三种操作,所以用两个
set
s
e
t
就可以维护。
set
s
e
t
是一棵平衡树,支持插入、删除、从小到大迭代等操作。
也可以使用离线的分块法,把输入的数据先排好序,按
n−−√
n
为块大小进行分块,然后用
cnt
c
n
t
数组维护此块中的此时的元素个数,然后按块查询中位数即可。
代码
set
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<set>
#define FOR(i,x,y) for(int i=(x);i<=(y);i++)
#define DOR(i,x,y) for(int i=(x);i>=(y);i--)
typedef long long LL;
using namespace std;
int num[10003];
char str[10];
int main()
{
int n,kase=0;
while(~scanf("%d",&n))
{
printf("Case #%d:\n",++kase);
set<int>left,right;
left.clear();right.clear();
int front=1,rear=1;
while(n--)
{
scanf("%s",str);
if(str[0]=='i')
{
scanf("%d",&num[rear]);
if(num[rear]>*right.begin())
right.insert(num[rear]);
else left.insert(num[rear]);
rear++;
}
else if(str[0]=='o')
{
if(left.find(num[front])!=left.end())
left.erase(num[front]);
else right.erase(num[front]);
front++;
}
else printf("%d\n",*right.begin());
if(right.size()>left.size()+1)
{
int t=*right.begin();
right.erase(t);
left.insert(t);
}
if(right.size()<left.size())
{
int t=*left.rbegin();
left.erase(t);
right.insert(t);
}
}
}
return 0;
}
分块
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#define FOR(i,x,y) for(int i=(x);i<=(y);i++)
#define DOR(i,x,y) for(int i=(x);i>=(y);i--)
typedef long long LL;
using namespace std;
int a[10003],cnt[103];
bool ins[103][103];
int opr[10003],t[10003];
int main()
{
int n,kase=0;
while(~scanf("%d",&n))
{
memset(cnt,0,sizeof(cnt));
memset(ins,0,sizeof(ins));
queue<int>q;
while(!q.empty())q.pop();
printf("Case #%d:\n",++kase);
int ele=0;
char str[10];
FOR(i,1,n)
{
scanf("%s",str);
if(str[0]=='i')
{
opr[i]=1;
scanf("%d",&t[i]);
a[++ele]=t[i];
q.push(a[ele]);
}
else if(str[0]=='o')
{
opr[i]=2;
t[i]=q.front();
q.pop();
}
else opr[i]=3;
}
sort(a+1,a+1+ele);
int bs=sqrt(ele),cur=0;
FOR(i,1,n)
{
if(opr[i]==1)
{
int pos=lower_bound(a+1,a+1+ele,t[i])-a;
ins[pos/bs][pos%bs]=1;
cnt[pos/bs]++;
cur++;
}
else if(opr[i]==2)
{
int pos=lower_bound(a+1,a+1+ele,t[i])-a;
ins[pos/bs][pos%bs]=0;
cnt[pos/bs]--;
cur--;
}
else
{
int j=0,k=(cur>>1)+1,p=0;
for(;k>cnt[p];k-=cnt[p++]);
for(;k;j++)if(ins[p][j])k--;
printf("%d\n",a[p*bs+(j-1)]);
}
}
}
return 0;
}