답안 #873225

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
873225 2023-11-14T16:37:22 Z boris_mihov Road Construction (JOI21_road_construction) C++17
5 / 100
10000 ms 89736 KB
#include <algorithm>
#include <iostream>
#include <numeric>
#include <cassert>
#include <vector>
#include <queue>

typedef long long llong;
const int MAXN = 250000 + 10;
const llong INF = 4e9 + 1;

int n, k;
struct Point
{
    llong x, y;
    friend bool operator < (const Point &a, const Point &b)
    {
        return a.x < b.x || (a.x == b.x && a.y < b.y);
    }
};

Point p[MAXN];
struct MST
{
    std::vector <llong> tree[4 * MAXN];
    void build(int l, int r, int node, llong nums[])
    {
        if (l == r)
        {
            tree[node].push_back(nums[l]);
            return;
        }

        int mid = (l + r) / 2;
        build(l, mid, 2*node, nums);
        build(mid + 1, r, 2*node + 1, nums);
        tree[node].reserve(r - l + 1);

        int lPtr = 0, rPtr = 0;
        for (int i = l ; i <= r ; ++i)
        {
            if (lPtr == tree[2*node].size())
            {
                tree[node].push_back(tree[2*node + 1][rPtr++]);
                continue;
            }

            if (rPtr == tree[2*node + 1].size())
            {
                tree[node].push_back(tree[2*node][lPtr++]);
                continue;
            }

            if (tree[2*node][lPtr] < tree[2*node + 1][rPtr])
            {
                tree[node].push_back(tree[2*node][lPtr++]);
            } else
            {
                tree[node].push_back(tree[2*node + 1][rPtr++]);
            }
        }
    }

    int binary(int node, llong value)
    {
        int l = -1, r = tree[node].size(), mid;
        while (l < r - 1)
        {
            mid = (l + r) / 2;
            if (tree[node][mid] <= value) l = mid;
            else r = mid;
        }

        return r;
    }

    int query(int l, int r, int node, int queryL, int queryR, llong queryValL, llong queryValR)
    {
        if (queryL <= l && r <= queryR)
        {
            return binary(node, queryValR) - binary(node, queryValL - 1);
        }

        int res = 0;
        int mid = (l + r) / 2;
        if (queryL <= mid) res += query(l, mid, 2*node, queryL, queryR, queryValL, queryValR);
        if (mid + 1 <= queryR) res += query(mid + 1, r, 2*node + 1, queryL, queryR, queryValL, queryValR);
        return res;
    }

    void build(llong nums[])
    {
        build(1, n, 1, nums);
    }

    int leftSearch(llong value)
    {
        int l = 0, r = n + 1, mid;
        while (l < r - 1)
        {
            mid = (l + r) / 2;
            if (p[mid].x < value) l = mid;
            else r = mid;
        }

        return r;
    }

    int rightSearch(llong value)
    {
        int l = 0, r = n + 1, mid;
        while (l < r - 1)
        {
            mid = (l + r) / 2;
            if (p[mid].x <= value) l = mid;
            else r = mid;
        }

        return l;
    }

    int query(Point p, llong len)
    {
        int qL = leftSearch(p.x - len);
        int qR = rightSearch(p.x + len);
        if (qL > qR) return 0;
        return query(1, n, 1, qL, qR, p.y - len, p.y + len);
    }

    std::pair <llong,int> searchNext(Point p, int currReach, llong minDist)
    {
        llong l = minDist - 1, r = INF, mid;
        while (l < r - 1)
        {
            mid = (l + r) / 2;
            if (query(p, mid) == currReach) l = mid;
            else r = mid;
        }

        return {r, query(p, r) - currReach};
    }
};  

MST tree;
struct Element
{
    int idx;
    llong dist;
    int count;
    int sum;

    friend bool operator < (const Element &a, const Element &b)
    {
        return a.dist > b.dist;
    }
};

llong nums[MAXN];
std::vector <llong> answer;
std::priority_queue <Element> pq;
void solve()
{
    for (int i = 1 ; i <= n ; ++i)
    {
        p[i] = {p[i].x - p[i].y, p[i].x + p[i].y};
    }

    std::sort(p + 1, p + 1 + n);
    for (int i = 1 ; i <= n ; ++i)
    {
        nums[i] = p[i].y;
    }

    tree.build(nums);
    for (int i = 1 ; i <= n ; ++i)
    {
        auto [to, cnt] = tree.searchNext(p[i], 0, 0);
        pq.push({i, to, cnt, cnt});
    }

    while (answer.size() < k)
    {
        auto [idx, dist, count, sum] = pq.top();
        pq.pop();

        for (int i = 0 ; i < count ; ++i)
        {
            answer.push_back(dist);
        }

        auto [to, cnt] = tree.searchNext(p[idx], sum, dist + 1);
        if (to < INF) pq.push({idx, to, cnt, sum + cnt});
    }

    for (int i = n ; i < k ; i += 2)
    {
        std::cout << answer[i] << '\n';
    }
}

void input()
{
    std::cin >> n >> k;
    for (int i = 1 ; i <= n ; ++i)
    {
        std::cin >> p[i].x >> p[i].y;
    }

    k = 2 * k + n;
}

void fastIOI()
{
    std::ios_base :: sync_with_stdio(0);
    std::cout.tie(nullptr);
    std::cin.tie(nullptr);
}

int main()
{
    fastIOI();
    input();
    solve();

    return 0;
}

Compilation message

road_construction.cpp: In member function 'void MST::build(int, int, int, llong*)':
road_construction.cpp:42:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   42 |             if (lPtr == tree[2*node].size())
      |                 ~~~~~^~~~~~~~~~~~~~~~~~~~~~
road_construction.cpp:48:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   48 |             if (rPtr == tree[2*node + 1].size())
      |                 ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
road_construction.cpp: In function 'void solve()':
road_construction.cpp:181:26: warning: comparison of integer expressions of different signedness: 'std::vector<long long int>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
  181 |     while (answer.size() < k)
      |            ~~~~~~~~~~~~~~^~~
# 결과 실행 시간 메모리 Grader output
1 Correct 5863 ms 33836 KB Output is correct
2 Correct 5790 ms 33920 KB Output is correct
3 Correct 4412 ms 33736 KB Output is correct
4 Correct 3576 ms 33916 KB Output is correct
5 Correct 5348 ms 32772 KB Output is correct
6 Correct 20 ms 27228 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 10069 ms 89736 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 10028 ms 85320 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Execution timed out 10028 ms 85320 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 5863 ms 33836 KB Output is correct
2 Correct 5790 ms 33920 KB Output is correct
3 Correct 4412 ms 33736 KB Output is correct
4 Correct 3576 ms 33916 KB Output is correct
5 Correct 5348 ms 32772 KB Output is correct
6 Correct 20 ms 27228 KB Output is correct
7 Execution timed out 10089 ms 56320 KB Time limit exceeded
8 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 5863 ms 33836 KB Output is correct
2 Correct 5790 ms 33920 KB Output is correct
3 Correct 4412 ms 33736 KB Output is correct
4 Correct 3576 ms 33916 KB Output is correct
5 Correct 5348 ms 32772 KB Output is correct
6 Correct 20 ms 27228 KB Output is correct
7 Execution timed out 10069 ms 89736 KB Time limit exceeded
8 Halted 0 ms 0 KB -