# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
1270733 | thuhienne | Mixture (BOI20_mixture) | C++20 | 0 ms | 0 KiB |
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using i64 = long long;
const long double PI = acosl(-1.0L);
const long double EPS = 1e-15L;
// pair hash for unordered_map
struct PairHash {
size_t operator()(pair<ll,ll> const &p) const noexcept {
return (uint64_t)(p.first * 1000003ULL) ^ (uint64_t)(p.second + 0x9e3779b97f4a7c15ULL);
}
};
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
#if 0
// Example: to debug with sample from statement
// 1 2 3
// 6
// A 5 6 7
// A 3 10 17
// R 1
// A 15 18 21
// A 5 10 15
// R 3
#endif
// read target
ll Sf, Pf, Gf;
if(!(cin >> Sf >> Pf >> Gf)) return 0;
vector<ll> Tf = {Sf, Pf, Gf};
// choose index base i where Tf[i] > 0
int idx = -1;
for(int t=0;t<3;t++) if(Tf[t] > 0) { idx = t; break; }
if(idx == -1) {
// should not happen per statement (Tf sum > 0)
return 0;
}
int j = (idx+1)%3;
int k = (idx+2)%3;
int N;
cin >> N;
// store per bottle info for removal
struct BottleInfo {
bool exists = false;
bool is_equal = false; // (A,B)==(0,0)
pair<ll,ll> key; // normalized direction representative
int sign; // +1 or -1 for which side
long double angle; // angle of (A,B)
};
vector<BottleInfo> bottles; bottles.reserve(N+5);
bottles.push_back(BottleInfo()); // 1-based indexing for add ids
int added_count = 0;
// data structures:
// count of exact equals (1-case)
int count_equal = 0;
// map from normalized rep (a,b) to pair(pos_count, neg_count)
unordered_map<pair<ll,ll>, pair<int,int>, PairHash> dirCount;
// for checking case 3: dynamic set of angles (for non-zero vectors)
set<long double> angles; // sorted distinct angles (but multiple bottles at same angle allowed; we use multiset of angles counts by storing duplicates too using multiset? We'll store duplicates by storing identical angles in multisetAngles.)
multiset<long double> multAngles; // allow duplicates
// to maintain gaps between consecutive angles, we use multiset of gaps
multiset<long double> gaps;
auto addGap = [&](long double g){ gaps.insert(g); };
auto eraseGap = [&](long double g){
auto it = gaps.find(g);
if(it != gaps.end()) gaps.erase(it);
};
// helper to get normalized representative and sign from (A,B)
auto normalizeAB = [&](ll A, ll B)->pair<pair<ll,ll>, int> {
if (A==0 && B==0) return {{0,0}, 0};
ll g = std::gcd( std::llabs(A), std::llabs(B) );
A /= g; B /= g;
// normalize sign so that representative has (a>0) or (a==0 && b>0)
if (A > 0 || (A==0 && B > 0)) {
return {{A,B}, +1};
} else {
return {{-A,-B}, -1};
}
};
// angl