Files
OI-source/2.1598.cpp
2023-08-03 09:22:52 +08:00

168 lines
4.1 KiB
C++

#include<bits/stdc++.h>
using namespace std;
struct Order
{
bool buy;
int size, price;
};
const int MAXN = 10010;
int n, orderIndice[MAXN], canceled[MAXN];
vector<Order> orders;
template<typename Compare>
struct OrderQueue
{
typedef set<int, Compare> _IntSet;
_IntSet eles;
void erase(int x) { eles.erase(eles.find(x)); }
bool empty() const { return eles.empty(); }
int top() const { return *eles.begin(); }
int pop()
{
int ans = *eles.begin();
eles.erase(eles.begin());
return ans;
}
void push(int oi) { eles.insert(oi); }
int size() const { return eles.size(); }
void clear() { eles.clear(); }
int topPrice() { return orders[top()].price; }
int topSize()
{
int tp = topPrice(), ans = 0;
for(auto i : eles){
const Order& o = orders[i];
if(o.price == tp) ans += o.size;
else break;
}
return ans;
}
};
struct BuyOrderCompare
{
bool operator() (int i, int j)
{
const Order &oi = orders[i], &oj = orders[j];
return oi.price > oj.price || (oi.price == oj.price && i < j);
}
};
struct SellOrderCompare
{
bool operator() (int i, int j)
{
const Order &oi = orders[i], &oj = orders[j];
return oi.price < oj.price || (oi.price == oj.price && i < j);
}
};
OrderQueue<BuyOrderCompare> buyQueue;
OrderQueue<SellOrderCompare> sellQueue;
void cancel(int ci)
{
int oi = orderIndice[ci];
if(canceled[oi]) return;
const Order& o = orders[oi];
if(o.buy) buyQueue.erase(oi);
else sellQueue.erase(oi);
canceled[oi] = 1;
}
void trade(int oi)
{
Order& o = orders[oi];
if(o.buy)
{
if(sellQueue.empty() || o.price < sellQueue.topPrice())
{
buyQueue.push(oi);
return;
}
int askPrice;
while(!sellQueue.empty() && o.size > 0 &&
o.price >= (askPrice = sellQueue.topPrice()))
{
int toi = sellQueue.top();
Order& to = orders[toi];
int tradeSize = min(o.size, to.size);
cout<<"TRADE "<<tradeSize<<" "<<askPrice<<endl;
to.size -= tradeSize;
o.size -= tradeSize;
sellQueue.pop();
if(to.size == 0) canceled[toi] = 1;
else sellQueue.push(toi);
}
if(o.size > 0) buyQueue.push(oi);
else canceled[oi] = 1;
return;
}
if(buyQueue.empty() || o.price > buyQueue.topPrice())
{
sellQueue.push(oi);
return;
}
int bidPrice;
while(!buyQueue.empty() && o.size > 0
&& o.price <= (bidPrice = buyQueue.topPrice()))
{
int toi = buyQueue.top();
Order& to = orders[toi];
int tradeSize = min(o.size, to.size);
cout<<"TRADE "<<tradeSize<<" "<<bidPrice<<endl;
to.size -= tradeSize;
o.size -= tradeSize;
buyQueue.pop();
if(to.size == 0) canceled[toi] = 1;
else buyQueue.push(toi);
}
if(o.size > 0) sellQueue.push(oi);
else canceled[oi] = 1;
}
void quote()
{
int bidSize = 0, bidPrice = 0, askSize = 0, askPrice = 99999;
if(!buyQueue.empty())
{
bidSize = buyQueue.topSize();
bidPrice = buyQueue.topPrice();
}
if(!sellQueue.empty())
{
askSize = sellQueue.topSize();
askPrice = sellQueue.topPrice();
}
cout<<"QUOTE "<<bidSize<<" "<<bidPrice<<" - "<<askSize<<" "<<askPrice<<endl;
}
int main()
{
#ifdef local
freopen("pro.in","r",stdin);
#endif
ios::sync_with_stdio(false);
string cmd;
bool first = true;
while(cin>>n)
{
if(first) first = false;
else cout<<endl;
fill_n(orderIndice, n, -1), fill_n(canceled, n, 0);
orders.clear(), buyQueue.clear(), sellQueue.clear();
for(int i=0;i<n;i++)
{
cin>>cmd;
if(cmd == "CANCEL")
{
int x; cin>>x;
cancel(x-1);
quote();
continue;
}
Order o;
cin>>o.size>>o.price;
o.buy = (cmd == "BUY");
orderIndice[i] = orders.size();
orders.push_back(o);
trade(orderIndice[i]);
quote();
}
}
return 0;
}