//Get inverse elements of positive integers that are <= bound template<typename T> voidGetInvs(T invs[], T p, T bound){ invs[1] = 1; for(int i = 2; i <= bound; ++i) invs[i] = (LL)(p - p / i) * invs[p % i] % p; }
template <typename T> T Sub(T x, int p){ return x < 0 ? x + p : x; }
structVEC { int x, y; VEC operator - (const VEC& b) const { return VEC{x - b.x, y - b.y}; } VEC rotleft(){ return VEC{-y, x}; } };
voidInsert(MyHashMap& ha, const VEC& now){ int& x = ha.find(now); if (x == ha.NOT_FOUND) { ha.emplace_shadow(now, 1); } else { ++x; } } intFind(MyHashMap& ha, const VEC& now){ int& x = ha.find(now); return x == ha.NOT_FOUND ? 0 : x; } intmain(){ static VEC ps[MAXN]; static MyHashMap rec[MAXN], as; int n, q; while (cin >> n >> q) { for (int i = 0; i < n; ++i) { rec[i].Init(); } as.Init(); for (int i = 0; i < n; ++i) { cin >> ps[i].x >> ps[i].y; } for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (i != j) { Insert(rec[i], ps[j] - ps[i]); } } } while (q--) { VEC a; cin >> a.x >> a.y; as.Init(); for (int i = 0; i < n; ++i) { Insert(as, ps[i] - a); } LL ans = 0; for (int i = 0; i < n; ++i) { ans += Find(as, (ps[i] - a).rotleft()); } ans >>= 1; for (int i = 0; i < n; ++i) { ans += Find(rec[i], (a - ps[i]).rotleft()); } cout << ans << endl; } }
return0; }
用unordered_map直接MLE了。HDU给的内存太少了(现场赛直接给了2G内存的)
代码:
#include<iostream> #include<unordered_map>
usingnamespace std;
#define MAXN 2011
typedeflonglong LL;
//Get inverse elements of positive integers that are <= bound template<typename T> voidGetInvs(T invs[], T p, T bound){ invs[1] = 1; for(int i = 2; i <= bound; ++i) invs[i] = (LL)(p - p / i) * invs[p % i] % p; }
template <typename T> T Sub(T x, int p){ return x < 0 ? x + p : x; }
structVEC { int x, y; VEC operator - (const VEC& b) const { return VEC{x - b.x, y - b.y}; } VEC rotleft(){ return VEC{-y, x}; } };
voidInsert(MyHashMap& ha, const VEC& now){ auto it = ha.find(now); if (it == ha.end()) { ha[now] = 1; } else { ++it->second; } } intFind(const MyHashMap& ha, const VEC& now){ auto it = ha.find(now); return it == ha.end() ? 0 : it->second; } intmain(){ static VEC ps[MAXN]; static MyHashMap rec[MAXN], as;
GetInvs(invs, p, p-1); for (int i = 0; i < MAXN; ++i) { rec[i].reserve(p); } as.reserve(p); int n, q; while (cin >> n >> q) { for (int i = 0; i < n; ++i) { cin >> ps[i].x >> ps[i].y; } for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (i != j) { Insert(rec[i], ps[j] - ps[i]); } } } while (q--) { VEC a; cin >> a.x >> a.y; as.clear(); for (int i = 0; i < n; ++i) { Insert(as, ps[i] - a); } LL ans = 0; for (int i = 0; i < n; ++i) { ans += Find(as, (ps[i] - a).rotleft()); } ans >>= 1; for (int i = 0; i < n; ++i) { ans += Find(rec[i], (a - ps[i]).rotleft()); } cout << ans << endl; } for (int i = 0; i < n; ++i) { rec[i].clear(); } as.clear(); }
return0; }
还有二分版(O(n^2 log n),8330ms)
#include<iostream> #include<algorithm>
usingnamespace std;
#define MAXN 2011
typedeflonglong LL;
structVEC { int x, y; voidclean(){ if (x < 0) { x = -x; y = -y; } elseif (0 == x) { y = abs(y); } } booloperator < (const VEC& b) const { return (LL)y * b.x < (LL)x * b.y; } VEC operator - (const VEC& b) const { return VEC{x - b.x, y - b.y}; } VEC rotleft(){ return VEC{-y, x}; } }; intmain(){ int n, q; static VEC ps[MAXN], recs[MAXN][MAXN], as[MAXN]; while (cin >> n >> q) { for (int i = 0; i < n; ++i) { cin >> ps[i].x >> ps[i].y; } for (int i = 0; i < n; ++i) { int t = 0; for (int j = 0; j < n; ++j) { if (i == j) continue; recs[i][t] = ps[j] - ps[i]; recs[i][t].clean(); ++t; } sort(recs[i], recs[i] + t); } while (q--) { VEC A; LL ans = 0; cin >> A.x >> A.y; for (int i = 0; i < n; ++i) { (as[i] = ps[i] - A).clean(); } sort(as, as + n); for (int i = 0; i < n; ++i) { VEC b = (ps[i] - A).rotleft(); b.clean(); ans += upper_bound(as, as + n, b) - lower_bound(as, as + n, b); } ans >>= 1; for (int i = 0; i < n; ++i) { VEC b = (A - ps[i]).rotleft(); b.clean(); ans += upper_bound(recs[i], recs[i] + n - 1, b) - lower_bound(recs[i], recs[i] + n - 1, b); } cout << ans << endl; } }