专栏文章

P4169 [Violet] 天使玩偶/SJY摆棋子の题解

P4169题解参与者 3已保存评论 4

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
4 条
当前快照
1 份
快照标识符
@minc6hxw
此快照首次捕获于
2025/12/02 00:01
3 个月前
此快照最后确认于
2025/12/02 00:01
3 个月前
查看原文
磕了 2727 发耗时 33 小时终于过了!!又是纯人类智慧首发!!

我们充分发扬人类智慧:
所有点按照 x+yx+yxyx-yxx 排序。
根据数学直觉,在排序后,离这个点最近的点一定在附近。
所以我们只取每个点前后 12001200 个点来计算答案。
这样速度快得飞起,在 n+m=1300000n+m=1300000 时都可以卡过。
注意要卡才能过,所以要打一颗平衡树,但是平衡树还是太慢了,用块状链表优化!
CodeCPP
#ifndef ONLINE_JUDGE
#pragma GCC optimize("O2", "O3", "Ofast", "inline")
#endif
#include <bits/stdc++.h>
using namespace std;

using it2 = array<int, 2>;

struct p0
{
    it2 x;
    p0(const it2 &y = {0, 0}) : x(y) {}
    bool operator<(const p0 &rhs) const { return x[0] + x[1] < rhs.x[0] + rhs.x[1]; }
    bool operator<=(const p0 &rhs) const { return x[0] + x[1] <= rhs.x[0] + rhs.x[1]; }
};
struct p1
{
    it2 x;
    p1(const it2 &y = {0, 0}) : x(y) {}
    bool operator<(const p1 &rhs) const { return x[0] - x[1] < rhs.x[0] - rhs.x[1]; }
    bool operator<=(const p1 &rhs) const { return x[0] - x[1] <= rhs.x[0] - rhs.x[1]; }
};
struct p2
{
    it2 x;
    p2(const it2 &y = {0, 0}) : x(y) {}
    bool operator<(const p2 &rhs) const { return x < rhs.x; }
    bool operator<=(const p2 &rhs) const { return x < rhs.x; }
};

template <typename Tp, size_t _B = 1536>
struct sortedvector
{
    using vecTp = vector<Tp>;
    using posTp = pair<size_t, size_t>;
    constexpr size_t B() { return _B; }
    size_t siz, bcnt;
    vector<vecTp> vecs;
    sortedvector() : siz(0ULL), bcnt(0ULL) {}
    sortedvector(const vecTp &vec) : siz(vec.size()), bcnt(0ULL)
    {
        vecTp *it = nullptr;
        for (size_t i = 0ULL; i < siz; ++i)
        {
            if (i % B() == 0)
            {
                vecs.emplace_back(vecTp());
                it = &vecs.at(bcnt++);
                it->reserve(B());
            }
            it->emplace_back(vec.at(i));
        }
    }
    posTp begin() const { return {0ULL, 0ULL}; }
    posTp end() const { return {bcnt, 0ULL}; }
    posTp next(const posTp &pos) const
    {
        if (pos.second + 1 == vecs[pos.first].size())
        {
            return {pos.first + 1, 0ULL};
        }
        else
        {
            return {pos.first, pos.second + 1};
        }
    }
    posTp prev(const posTp &pos) const
    {
        if (pos.second == 0ULL)
        {
            return {pos.first - 1, vecs[pos.first - 1].size() - 1ULL};
        }
        else
        {
            return {pos.first, pos.second - 1};
        }
    }
    posTp lower_bound(const Tp &val) const
    {
        for (size_t i = 0ULL; i < bcnt; ++i)
        {
            if (val <= vecs.at(i).back())
            {
                return {i, std::lower_bound(vecs[i].begin(), vecs[i].end(), val) - vecs[i].begin()};
            }
        }
        return {bcnt, 0ULL};
    }
    void insert(const Tp &val)
    {
        posTp pos = lower_bound(val);
        vecTp &vec = vecs.at(pos.first);
        vec.emplace(vec.begin() + pos.second, val);
        ++siz;
        if (vec.size() > B() << 1)
        {
            vecTp half(vec.begin() + B(), vec.end());
            vec.erase(vec.begin() + B(), vec.end());
            vecs.emplace(vecs.begin() + pos.first + 1, half);
            ++bcnt;
        }
    }
    size_t size() const { return siz; }
    Tp &operator[](posTp i) { return vecs.at(i.first).at(i.second); }
    const Tp &operator[](posTp i) const { return vecs.at(i.first).at(i.second); }
};

#define printf __builtin_printf
#ifdef ONLINE_JUDGE
#define getchar getchar_unlocked
#else
#define getchar _getchar_nolock
#endif
#define rd read()
int read()
{
    int ch = 0, res = 0;
    while (!isdigit(ch))
    {
        ch = getchar();
    }
    while (isdigit(ch))
    {
        res = res * 10 + ch - '0', ch = getchar();
    }
    return res;
}

int n, m, t;
vector<it2> a;

signed main()
{
    n = rd, m = rd, a.resize(n);
    for (int i = 0; i < n; ++i)
    {
        a[i] = {rd, rd};
    }
    n += 4;
    a.push_back({0x114514, 0x114514});
    a.push_back({-0x114514, 0x114514});
    a.push_back({-0x114514, -0x114514});
    a.push_back({0x114514, -0x114514});

    vector<p0> tmp0(n);
    for (int i = 0; i < n; ++i)
    {
        tmp0[i] = p0(a[i]);
    }
    sort(tmp0.begin(), tmp0.end());
    sortedvector<p0> a0(tmp0);
    vector<p1> tmp1(n);
    for (int i = 0; i < n; ++i)
    {
        tmp1[i] = p1(a[i]);
    }
    sort(tmp1.begin(), tmp1.end());
    sortedvector<p1> a1(tmp1);
    vector<p2> tmp2(n);
    for (int i = 0; i < n; ++i)
    {
        tmp2[i] = p2(a[i]);
    }
    sort(tmp2.begin(), tmp2.end());
    sortedvector<p2> a2(tmp2);

    int op;
    it2 x;
    while (m--)
    {
        op = rd, x = {rd, rd};
        if (op == 1)
        {
            ++n;
            a0.insert(p0(x));
            a1.insert(p1(x));
            a2.insert(p2(x));
        }
        else
        {
            int res = 0x114514;
            {
                auto p = a0.lower_bound(x);
                {
                    int cnt = 1200;
                    for (auto it = p; it != a0.begin() && cnt; it = a0.prev(it), --cnt)
                    {
                        res = min(res, abs(a0[it].x[0] - x[0]) + abs(a0[it].x[1] - x[1]));
                    }
                }
                {
                    int cnt = 1200;
                    for (auto it = p; it != a0.end() && cnt; it = a0.next(it), --cnt)
                    {
                        res = min(res, abs(a0[it].x[0] - x[0]) + abs(a0[it].x[1] - x[1]));
                    }
                }
            }
            {
                auto p = a1.lower_bound(x);
                {
                    int cnt = 1200;
                    for (auto it = p; it != a1.begin() && cnt; it = a1.prev(it), --cnt)
                    {
                        res = min(res, abs(a1[it].x[0] - x[0]) + abs(a1[it].x[1] - x[1]));
                    }
                }
                {
                    int cnt = 1200;
                    for (auto it = p; it != a1.end() && cnt; it = a1.next(it), --cnt)
                    {
                        res = min(res, abs(a1[it].x[0] - x[0]) + abs(a1[it].x[1] - x[1]));
                    }
                }
            }
            {
                auto p = a2.lower_bound(x);
                {
                    int cnt = 1200;
                    for (auto it = p; it != a2.begin() && cnt; it = a2.prev(it), --cnt)
                    {
                        res = min(res, abs(a2[it].x[0] - x[0]) + abs(a2[it].x[1] - x[1]));
                    }
                }
                {
                    int cnt = 1200;
                    for (auto it = p; it != a2.end() && cnt; it = a2.next(it), --cnt)
                    {
                        res = min(res, abs(a2[it].x[0] - x[0]) + abs(a2[it].x[1] - x[1]));
                    }
                }
            }
            printf("%d\n", res);
        }
    }

    return 0;
}

评论

4 条评论,欢迎与作者交流。

正在加载评论...