CCF 201412-3 Llamada a subasta suma de prefijo dicotómico
#include<iostream>
using namespace std;
#include<string>
#include<algorithm>
#include<vector>
typedef long long LL;
const int MAXN=5005;
LL buyy,sell,ans;
double mm_bes;
double sum_buy[MAXN]; //前缀和
double sum_sell[MAXN]; //前缀和
vector<double> money; //存所有可能的开盘价
string ss;
double mm;
int nn;
int rr;
struct GG{
double money;
int num;
int ok; //ok=1表示有效
bool operator <(const GG aa) const{
return money<aa.money;
}
}gg_buy[MAXN],gg_sell[MAXN];
int get_buy(double x) //查找>=x 的左边界
{
int l=1; //[l,r)
int r=rr+1;
int mid;
while(l<r)
{
mid=(l+r)/2;
if(gg_buy[mid].money>=x)
{
r=mid;
}else l=mid+1;
}
if(l==rr+1) //如果不存在返回-1
return -1;
return l;
}
int get_sell(double x) //查找<=x的有边界
{
int l=1;
int r=rr+1;
int mid;
while(l<r)
{
mid=(l+r)/2;
if(gg_sell[mid].money<=x)
{
l=mid+1;
}else r=mid;
}
if(l==1) //如果不存在返回-1
return -1;
return l-1;
}
int main()
{
rr=1;
double mon;
int numm;
while(cin>>ss)
{
if(ss=="cancel")
{
scanf("%d",&nn);
gg_buy[nn].ok=0;
gg_sell[nn].ok=0;
}else
{
if(ss=="buy")
{
gg_buy[rr].ok=1;
scanf("%lf %d",&mon,&numm);
gg_buy[rr].money=mon;
gg_buy[rr].num=numm;
}else
{
gg_sell[rr].ok=1;
scanf("%lf %d",&mon,&numm);
gg_sell[rr].money=mon;
gg_sell[rr].num=numm;
}
money.push_back(mon);
}
rr++;
}
rr--;
sort(gg_sell+1,gg_sell+1+rr);
sort(gg_buy+1,gg_buy+1+rr);
for(int i=1;i<=rr;i++)
{
if(gg_buy[i].ok)
sum_buy[i]=gg_buy[i].num+sum_buy[i-1];
else sum_buy[i]=sum_buy[i-1];
if(gg_sell[i].ok)
sum_sell[i]=gg_sell[i].num+sum_sell[i-1];
else sum_sell[i]=sum_sell[i-1];
}
int buy_xb;
int sell_xb;
for(int i=0;i<money.size();i++)
{
buyy=0;
sell=0;
double altol=0;
buy_xb=get_buy(money[i]);
sell_xb=get_sell(money[i]);
buyy=sum_buy[rr]-sum_buy[buy_xb-1];
if(buy_xb==-1)
continue;
sell=sum_sell[sell_xb];
if(sell_xb==-1)
continue;
altol=min(buyy,sell);
if(altol>ans || (altol==ans && money[i]>mm_bes))
{
ans=altol;
mm_bes=money[i];
}
}
printf("%.2lf %lld",mm_bes,ans);
return 0;
}