提交记录 19092


用户 题目 状态 得分 用时 内存 语言 代码长度
saffah 1009. 测测你的三维数点 Accepted 100 1.897 s 128940 KB C++ 5.87 KB
提交时间 评测时间
2023-02-06 09:12:39 2023-02-06 09:12:44
#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);
}

CompilationN/AN/ACompile OKScore: N/A

Testcase #11.897 s125 MB + 940 KBAcceptedScore: 100


Judge Duck Online | 评测鸭在线
Server Time: 2024-05-15 20:19:19 | Loaded in 1 ms | Server Status
个人娱乐项目,仅供学习交流使用