题目地址 : http://acm.hdu.edu.cn/showproblem.php?pid=4302
2012年 多校第一场的题目,很大一部分人是用BIT(树状数组)做的,甚至B哥还TLE了几次。。。
当然过的人,时间复杂度也比我高得多。。。
一开始看了下,觉得用线段树,或者树状数组。。。
后来突然想到优先队列可搞。。。。
于是搞之~~ 很基础的优先队列题目。。。
用一个最大堆和一个最小堆,两堆堆顶的交接处即是老鼠的位置。
若新放入的蛋糕在老鼠右边,就加入最小堆;在老鼠左边,则放入最大堆。
老鼠每次吃的话,只需要寻找两边其中一个最近的堆顶。
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
struct mn{
int a;
mn(int x){
a=x;
}
mn(){}
bool friend operator<(mn x,mn y){
return x.a>y.a;
}
};
priority_queue<int>qmx;
priority_queue<mn>qmn;
int l,n;
int lef,rit,now,last;
__int64 mov;
void gr(){
mov+=rit;
last=2;
now=qmn.top().a;
qmn.pop();
}
void gl(){
mov+=lef;
last=1;
now=qmx.top();
qmx.pop();
}
void init_(){
now=0;
mov=0;
last=2;
while(!qmx.empty()) qmx.pop();
while(!qmn.empty()) qmn.pop();
}
int main(){
int t,tt;
int op,i,j,a;
scanf("%d",&t);
for(tt=1;tt<=t;tt++){
scanf("%d%d",&l,&n);
init_();
while(n--){
scanf("%d",&op);
if(op==0){
scanf("%d",&a);
if(a>=now)
qmn.push(mn(a));
else qmx.push(a);
}
else{
if(!qmn.empty())
rit=qmn.top().a-now;
else rit=-1;
if(!qmx.empty())
lef=now-qmx.top();
else
lef=-1;
if(lef==-1 && rit==-1) continue;
else if(lef==-1) gr();
else if(rit==-1) gl();
else{
if(rit==lef){
if(last==2) gr();
else gl();
}
else if(lef<rit) gl();
else gr();
}
}
}
printf("Case %d: %I64d\n",tt,mov);
}
return 0;
}