This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
//#define debug
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> ii;
typedef long double ld;
#define SZ(x) ((int)x.size())
const int SQ = 316;
const int N = (int)3e4+5;
struct point {
ll x, y;
int t, idx;
point(ll _x, ll _y, int _t, int _idx) : x(_x), y(_y), t(_t), idx(_idx) {}
point() { x = y = 0, t = idx = 0; }
inline bool operator<(const point &other) const;
} origin;
inline bool ccw(const point &a, const point &b, const point &c) {
return a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y) > 0;
}
struct TData {
int lo, hi, id;
TData(int _lo, int _hi, int _id) : lo(_lo), hi(_hi), id(_id) {}
TData() {}
inline bool operator<(const TData &other) const {
return hi < other.hi;
}
};
int n, m, q;
vector<ii> b[N], c[N];
ll res[N*10], cnt[N];
vector<point> dragon, dragon2;
point human1, mid, human2;
vector<TData> g[178];
vector<int> pos_t[N];
inline bool point::operator <(const point &other) const {
if (ccw(human2, *this, human1) && !ccw(human2, other, human1)) {
return true;
} else if (!ccw(human2, *this, human1) && ccw(human2, other, human1)) {
return false;
}
return ccw(origin, *this, other);
}
struct fenwick {
private:
vector<int> tree;
int _n;
public:
void init(int _sz) {
tree.resize(_sz + 2);
_n = _sz;
}
void update(int idx, int val) {
for (; idx <= _n; idx += idx & -idx)
tree[idx] += val;
}
int read(int idx) {
int ans = 0;
for (; idx; idx -= idx & -idx)
ans += tree[idx];
return ans;
}
void clear() {
if (!SZ(tree)) return;
tree.clear();
}
} tr[N];
const int SQN = 173;
void solve(ll mul, ll mul2) {
sort(dragon.begin(), dragon.end());
for (int i = 0; i <= SQN+1; ++i) g[i].clear();
for (int i = 0; i < n; ++i) {
point tmp = point(mul2 * dragon[i].x, mul2 * dragon[i].y, 0, 0);
int lo = upper_bound(dragon.begin(), dragon.end(), tmp) - dragon.begin();
int hi = upper_bound(dragon.begin(), dragon.end(), human1) - dragon.begin();
lo -= (mul2 == 1 && !ccw(human2, dragon[i], human1));
if (hi < lo) swap(lo, hi);
--hi;
if (lo <= hi) {
g[lo / SQN].push_back(TData(lo, hi, dragon[i].t));
}
}
for (int i = 0; i <= SQN+1; ++i) {
sort(g[i].begin(), g[i].end());
}
for (int i = 0; i <= SQN+1; ++i) {
if (!SZ(g[i])) continue;
memset(cnt, 0, sizeof(cnt));
int Lmax = -1;
for (const TData &v : g[i]) {
Lmax = max(Lmax, v.lo);
}
int curL = Lmax - 1;
for (const TData &v : g[i]) {
int L = v.lo, R = v.hi, t = v.id;
if (R < Lmax) {
for (int j = L; j <= R; ++j) {
++cnt[dragon[j].t];
}
} else {
while (curL < R) {
++curL;
++cnt[dragon[curL].t];
}
for (int j = L; j < Lmax; ++j) {
++cnt[dragon[j].t];
}
}
for (int j = 0; j < SZ(b[t]); ++j) {
res[b[t][j].second] += mul * cnt[b[t][j].first];
}
if (mul2 == -1) {
for (int j = 0; j < SZ(c[t]); ++j) {
res[c[t][j].second] += mul * cnt[c[t][j].first];
}
}
if (R < Lmax) {
for (int j = L; j <= R; ++j) {
--cnt[dragon[j].t];
}
} else {
for (int j = L; j < Lmax; ++j) {
--cnt[dragon[j].t];
}
}
}
}
}
int pos[N];
void solve2(vector<point> &a1, vector<point> &a2) {
memset(pos, 0, sizeof(pos));
for (int i = 1; i <= m; ++i) {
pos_t[i].clear();
tr[i].clear();
}
for (int i = 0; i < SZ(a2); ++i) {
pos[a2[i].idx] = i;
pos_t[a2[i].t].push_back(i);
}
for (int i = 1; i <= m; ++i) {
if (!SZ(pos_t[i])) continue;
tr[i].init(SZ(pos_t[i]));
}
for (int i = 0; i < SZ(a1); ++i) {
const point &v = a1[i];
int pvidx = pos[v.idx];
int idx = lower_bound(pos_t[v.t].begin(), pos_t[v.t].end(), pvidx) - pos_t[v.t].begin() + 1;
tr[v.t].update(idx, 1);
for (int j = 0; j < SZ(b[v.t]); ++j) {
int idx2 = upper_bound(pos_t[b[v.t][j].first].begin(), pos_t[b[v.t][j].first].end(), pvidx) - pos_t[b[v.t][j].first].begin();
int val = tr[b[v.t][j].first].read(idx2);
res[b[v.t][j].second] += (ll)(idx2 - val);
}
for (int j = 0; j < SZ(c[v.t]); ++j) {
int idx2 = upper_bound(pos_t[c[v.t][j].first].begin(), pos_t[c[v.t][j].first].end(), pvidx) - pos_t[c[v.t][j].first].begin();
int val = tr[c[v.t][j].first].read(idx2);
res[c[v.t][j].second] += (ll)(idx2 - val);
}
}
}
vector<point> upper1, upper2;
vector<point> lower1, lower2;
int main() {
#ifdef debug
clock_t tStart = clock();
//freopen("inp.txt", "rt", stdin);
#endif
ios::sync_with_stdio(0); cin.tie(0);
cin >> n >> m;
dragon.resize(n), dragon2.resize(n);
for (int i = 0; i < n; ++i) {
cin >> dragon[i].x >> dragon[i].y >> dragon[i].t;
dragon[i].idx = i;
}
cin >> human1.x >> human1.y >> human2.x >> human2.y;
//move the coordinates
if (human1.y > human2.y) swap(human1, human2);
mid = human1;
human2.x -= mid.x, human2.y -= mid.y;
human1 = point(-human2.x, -human2.y, 0, 0);
for (int i = 0; i < n; ++i) {
dragon[i].x -= mid.x;
dragon[i].y -= mid.y;
}
mid = point(0, 0, 0, 0);
cin >> q;
for (int i = 0, x, y; i < q; ++i) {
cin >> x >> y;
b[x].push_back(ii(y, i));
}
for (int i = 1; i <= m; ++i) {
if (SZ(b[i]) > SQ) {
for (int j = 0; j < SZ(b[i]); ++j) {
c[b[i][j].first].push_back(ii(i, b[i][j].second));
}
b[i].clear();
}
}
solve(-1, -1);
solve(-1, 1);
for (int i = 0; i < n; ++i) {
dragon2[i].x = dragon[i].x - human2.x;
dragon2[i].y = dragon[i].y - human2.y;
dragon2[i].idx = dragon[i].idx;
dragon2[i].t = dragon[i].t;
}
point pt_tmp1 = human1, pt_tmp2 = human2;
human1 = point(mid.x - human2.x, mid.y - human2.y, 0, 0);
human2 = point(-human1.x, -human1.y, 0, 0);
dragon.swap(dragon2);
solve(1, -1);
solve(1, 1);
dragon.swap(dragon2);
point pt_tmp3 = human1, pt_tmp4 = human2;
auto something = [] (vector<point> &re, const vector<point> &src, bool mode) {
for (int i = 0; i < SZ(src); ++i) {
const point &v = src[i];
if (ccw(human2, v, human1) == mode) {
re.push_back(v);
}
}
};
human1 = pt_tmp1, human2 = pt_tmp2;
something(upper1, dragon, 1);
something(lower2, dragon, 0);
human1 = pt_tmp3, human2 = pt_tmp4;
something(upper2, dragon2, 1);
something(lower1, dragon2, 0);
solve2(upper1, upper2);
solve2(lower1, lower2);
for (int i = 0; i < q; ++i) {
cout << res[i] << "\n";
}
#ifdef debug
cout << "Total time: " << (int)(1000.0 * (double)(clock() - tStart) / CLOCKS_PER_SEC) << "ms\n";
#endif
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |