제출 #1363553

#제출 시각아이디문제언어결과실행 시간메모리
1363553alexddIOI 바이러스 (JOI21_fever)C++20
6 / 100
1 ms344 KiB
#include <bits/stdc++.h>
using namespace std;

#define int long long

const int MAXN = 1e5 + 5;
const int INF = 1e18;

const bool LINES = 0;


int n;
int x[MAXN], y[MAXN], d1[MAXN], d2[MAXN];

unordered_map<int, set<pair<int,int>>> of_d1, of_d2, of_x[2], of_y[2];
void baga(int id)
{
    of_d1[d1[id]].insert({x[id], id});
    of_d2[d2[id]].insert({x[id], id});

    //of_x[x[id] % 2][x[id]].insert({y[id] / 2, id});
    //of_y[y[id] % 2][y[id]].insert({x[id] / 2, id});
}
void scoate(int id)
{
    of_d1[d1[id]].erase({x[id], id});
    of_d2[d2[id]].insert({x[id], id});

    of_x[x[id] % 2][x[id]].erase({y[id] / 2, id});
    of_y[y[id] % 2][y[id]].erase({x[id] / 2, id});
}

int dist[MAXN];
priority_queue<pair<int, pair<int,int>>> pq;//{-dist, {nod, dir}}

vector<int> aux;


int myd;
void add_to_pq(int nod, int dir, int t)
{
    if(dist[nod] <= t)
        return;
    //assert(t >= myd);

    if(t < myd)
        return;

    aux.push_back(nod);
    dist[nod] = t;
    pq.push({-dist[nod], {nod, dir}});
}

int solve(int root_dir)
{
    for(int i=1;i<=n;i++)
    {
        dist[i] = INF;
        baga(i);
    }


    while(!pq.empty())
        pq.pop();

    add_to_pq(1, root_dir, 0);
    scoate(1);

    while(!pq.empty())
    {

        int cdist = -pq.top().first, nod = pq.top().second.first, dir = pq.top().second.second;
        pq.pop();

        //assert(cdist == dist[nod]);
        if(cdist != dist[nod])
            continue;

        myd = dist[nod];

        //add equal x and y cases-------------------------------------------------------------

        aux.clear();

        int ct;
        if(dir == 0)
        {
            //cv - x[nod] > dist[nod] => cv > dist[nod] + x[nod]
            auto it1 = of_d1[d1[nod]].lower_bound({dist[nod] + x[nod], INF});
            while(it1 != of_d1[d1[nod]].end())
            {
                ct = (*it1).first - x[nod];
                add_to_pq((*it1).second, 3, ct);

                it1 = of_d1[d1[nod]].erase(it1);
            }

            auto it2 = of_d2[d2[nod]].lower_bound({dist[nod] + x[nod], INF});
            while(it2 != of_d2[d2[nod]].end())
            {
                ct = (*it2).first - x[nod];
                add_to_pq((*it2).second, 2, ct);

                it2 = of_d2[d2[nod]].erase(it2);
            }

            if(LINES)
            {
                auto it3 = of_y[y[nod] % 2][y[nod]].lower_bound({x[nod] / 2 + dist[nod], INF});
                while(it3 != of_y[y[nod] % 2][y[nod]].end())
                {
                    ct = (*it3).first - x[nod] / 2;
                    add_to_pq((*it3).second, 1, ct);

                    it3 = of_y[y[nod] % 2][y[nod]].erase(it3);
                }
            }
        }
        else if(dir == 1)
        {
            auto it1 = of_d1[d1[nod]].lower_bound({x[nod] - dist[nod], 0});
            while(it1 != of_d1[d1[nod]].begin())
            {
                it1--;

                ct = x[nod] - (*it1).first;
                add_to_pq((*it1).second, 2, ct);

                it1 = of_d1[d1[nod]].erase(it1);
            }

            auto it2 = of_d2[d2[nod]].lower_bound({x[nod] - dist[nod], 0});
            while(it2 != of_d2[d2[nod]].begin())
            {
                it2--;

                ct = x[nod] - (*it2).first;
                add_to_pq((*it2).second, 3, ct);

                it2 = of_d2[d2[nod]].erase(it2);
            }

            if(LINES)
            {
                auto it3 = of_y[y[nod] % 2][y[nod]].lower_bound({x[nod] / 2 - dist[nod], 0});
                while(it3 != of_y[y[nod] % 2][y[nod]].begin())
                {
                    it3--;

                    ct = x[nod] / 2 - (*it3).first;
                    add_to_pq((*it3).second, 0, ct);

                    it3 = of_y[y[nod] % 2][y[nod]].erase(it3);
                }
            }
        }
        else if(dir == 2)
        {
            auto it1 = of_d1[d1[nod]].lower_bound({dist[nod] + x[nod], INF});
            while(it1 != of_d1[d1[nod]].end())
            {
                ct = (*it1).first - x[nod];
                add_to_pq((*it1).second, 1, ct);

                it1 = of_d1[d1[nod]].erase(it1);
            }

            auto it2 = of_d2[d2[nod]].lower_bound({x[nod] - dist[nod], 0});
            while(it2 != of_d2[d2[nod]].begin())
            {
                it2--;

                ct = x[nod] - (*it2).first;
                add_to_pq((*it2).second, 0, ct);

                it2 = of_d2[d2[nod]].erase(it2);
            }

            if(LINES)
            {
                auto it3 = of_x[x[nod] % 2][x[nod]].lower_bound({y[nod] / 2 + dist[nod], INF});
                while(it3 != of_x[x[nod] % 2][x[nod]].end())
                {
                    ct = (*it3).first - y[nod] / 2;
                    add_to_pq((*it3).second, 3, ct);

                    it3 = of_x[x[nod] % 2][x[nod]].erase(it3);
                }
            }
        }
        else
        {
            assert(dir == 3);

            auto it1 = of_d1[d1[nod]].lower_bound({x[nod] - dist[nod], 0});
            while(it1 != of_d1[d1[nod]].begin())
            {
                it1--;

                ct = x[nod] - (*it1).first;
                add_to_pq((*it1).second, 0, ct);

                it1 = of_d1[d1[nod]].erase(it1);
            }

            auto it2 = of_d2[d2[nod]].lower_bound({dist[nod] + x[nod], INF});
            while(it2 != of_d2[d2[nod]].end())
            {
                ct = (*it2).first - x[nod];
                add_to_pq((*it2).second, 1, ct);

                it2 = of_d2[d2[nod]].erase(it2);
            }

            if(LINES)
            {
                auto it3 = of_x[x[nod] % 2][x[nod]].lower_bound({y[nod] / 2 - dist[nod], 0});
                while(it3 != of_x[x[nod] % 2][x[nod]].begin())
                {
                    it3--;

                    ct = y[nod] / 2 - (*it3).first;
                    add_to_pq((*it3).second, 2, ct);

                    it3 = of_x[x[nod] % 2][x[nod]].erase(it3);
                }
            }
        }

        for(int v:aux)
            scoate(v);
    }

    int cnt = 0;
    for(int i=1;i<=n;i++)
        if(dist[i] < INF)
            cnt++;
    return cnt;
}

signed main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>x[i]>>y[i];

        x[i] = x[i] * 2;
        y[i] = y[i] * 2;

        d1[i] = x[i] + y[i];
        d2[i] = x[i] - y[i];
    }

    int mxm = 0;
    for(int dir=0;dir<4;dir++)
        mxm = max(mxm, solve(dir));
    cout<<mxm;
    return 0;
}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…