#pragma GCC target("avx2")
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <random>
#include <set>
#include <tuple>
#include <vector>
using namespace std;
static unsigned* out;
static void count_1d_static(vector<tuple<unsigned, unsigned>>& items, unsigned l, unsigned m, unsigned r) {
unsigned i = l, cnt = 0;
for (unsigned j = m; j < r; j++) {
auto& [x, q] = items[j];
while (i < m && get<0>(items[i]) < x)
i++, cnt++;
out[q] += cnt;
}
}
template <bool Root = false>
static unsigned count_1d_dynamic_recursion(vector<tuple<unsigned, unsigned>>& items, vector<tuple<unsigned, unsigned>>* aux, int id, unsigned l, unsigned r) {
// queries, points
if (r - l <= 16) {
for (unsigned i = l; i < r; i++)
if (get<1>(items[i])) {
unsigned tmp = 0;
for (unsigned j = l; j < i; j++)
if (!get<1>(items[j]) && get<0>(items[j]) < get<0>(items[i]))
tmp++;
out[get<1>(items[i])] += tmp;
}
sort(items.begin() + l, items.begin() + r, [](const auto& a, const auto& b) {
if (!!get<1>(a) != !!get<1>(b))
return !!get<1>(a) > !!get<1>(b);
return a < b;
});
copy(items.begin() + l, items.begin() + r, aux[id].begin() + l);
unsigned ret = l;
while (ret < r && get<1>(items[ret]))
ret++;
return ret;
}
unsigned m = (l + r) / 2;
unsigned lm = count_1d_dynamic_recursion(items, aux, !id, l, m);
unsigned mr = count_1d_dynamic_recursion(items, aux, !id, m, r);
count_1d_static(aux[!id], lm, m, mr);
if (Root)
return -1;
unsigned mq = mr - m + lm;
merge(aux[!id].begin() + l, aux[!id].begin() + lm, aux[!id].begin() + m, aux[!id].begin() + mr, aux[id].begin() + l);
merge(aux[!id].begin() + lm, aux[!id].begin() + m, aux[!id].begin() + mr, aux[!id].begin() + r, aux[id].begin() + mq);
return mq;
}
static void count_1d_dynamic(vector<tuple<unsigned, unsigned>>& items, vector<tuple<unsigned, unsigned>>* aux) {
count_1d_dynamic_recursion<true>(items, aux, 0, 0, items.size());
}
static void count_2d_static(vector<tuple<unsigned, unsigned, unsigned>>& items, vector<tuple<unsigned, unsigned, unsigned>>& aux, vector<tuple<unsigned, unsigned>>* aux_1d, unsigned l, unsigned m, unsigned r) {
merge(items.begin() + l, items.begin() + m, items.begin() + m, items.begin() + r, aux.begin() + l, [](const auto& a, const auto& b) {
if (get<0>(a) != get<0>(b))
return get<0>(a) < get<0>(b);
return !!get<2>(a) > !!get<2>(b);
});
vector<tuple<unsigned, unsigned>> count_1d;
count_1d.reserve(r - l);
for (unsigned i = l; i < r; i++)
count_1d.emplace_back(get<1>(aux[i]), get<2>(aux[i]));
count_1d_dynamic(count_1d, aux_1d);
}
template <bool Root = false>
static unsigned count_2d_dynamic_recursion(vector<tuple<unsigned, unsigned, unsigned>>& items, vector<tuple<unsigned, unsigned, unsigned>>* aux, vector<tuple<unsigned, unsigned>>* aux_1d, int id, unsigned l, unsigned r) {
// queries, points
if (r - l <= 24) {
for (unsigned i = l; i < r; i++)
if (get<2>(items[i])) {
unsigned tmp = 0;
for (unsigned j = l; j < i; j++)
if (!get<2>(items[j]) && get<0>(items[j]) < get<0>(items[i]) && get<1>(items[j]) < get<1>(items[i]))
tmp++;
out[get<2>(items[i])] += tmp;
}
sort(items.begin() + l, items.begin() + r, [](const auto& a, const auto& b) {
if (!!get<2>(a) != !!get<2>(b))
return !!get<2>(a) > !!get<2>(b);
return a < b;
});
copy(items.begin() + l, items.begin() + r, aux[id].begin() + l);
unsigned ret = l;
while (ret < r && get<2>(items[ret]))
ret++;
return ret;
}
unsigned m = (l + r) / 2;
unsigned lm = count_2d_dynamic_recursion(items, aux, aux_1d, !id, l, m);
unsigned mr = count_2d_dynamic_recursion(items, aux, aux_1d, !id, m, r);
count_2d_static(aux[!id], items, aux_1d, lm, m, mr);
if (Root)
return -1;
unsigned mq = mr - m + lm;
merge(aux[!id].begin() + l, aux[!id].begin() + lm, aux[!id].begin() + m, aux[!id].begin() + mr, aux[id].begin() + l);
merge(aux[!id].begin() + lm, aux[!id].begin() + m, aux[!id].begin() + mr, aux[!id].begin() + r, aux[id].begin() + mq);
return mq;
}
static void count_2d_dynamic(vector<tuple<unsigned, unsigned, unsigned>>& items) {
vector<tuple<unsigned, unsigned, unsigned>> aux[2];
aux[0].resize(items.size());
aux[1].resize(items.size());
vector<tuple<unsigned, unsigned>> aux_1d[2];
aux_1d[0].resize(items.size());
aux_1d[1].resize(items.size());
count_2d_dynamic_recursion<true>(items, aux, aux_1d, 0, 0, items.size());
}
static void count_3d_static_same(vector<tuple<unsigned, unsigned, unsigned, unsigned>>& queries) {
vector<tuple<unsigned, unsigned, unsigned>> count_2d;
int t = queries.size() * 2;
count_2d.reserve(t);
queries.emplace_back(-1, -1, -1, 0);
unsigned i = 0, j = 0;
while (t--) {
if (get<0>(queries[i]) < get<0>(queries[j])) {
count_2d.emplace_back(get<1>(queries[i]), get<2>(queries[i]), 0);
i++;
} else {
count_2d.emplace_back(get<1>(queries[j]), get<2>(queries[j]), get<3>(queries[j]));
j++;
}
}
count_2d_dynamic(count_2d);
queries.pop_back();
}
void count_3d(int n, const unsigned *x, const unsigned *y, const unsigned *z, unsigned *out) {
::out = out - 1;
vector<tuple<unsigned, unsigned, unsigned, unsigned>> queries;
queries.reserve(n + 1);
for (int i = 0; i < n; i++)
queries.emplace_back(x[i], y[i], z[i], i + 1);
sort(queries.begin(), queries.end());
count_3d_static_same(queries);
}
Compilation | N/A | N/A | Compile OK | Score: N/A | 显示更多 |
Testcase #1 | 1.897 s | 125 MB + 940 KB | Accepted | Score: 100 | 显示更多 |