제출 #1324585

#제출 시각아이디문제언어결과실행 시간메모리
1324585Zbyszek99IOI 바이러스 (JOI21_fever)C++20
100 / 100
2194 ms87660 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#define ll long long
#define ld long double
#define ull unsigned long long
#define ff first
#define ss second
#define pii pair<int,int>
#define pll pair<long long, long long>
#define vi vector<int>
#define vl vector<long long>
#define pb push_back
#define rep(i, b) for(int i = 0; i < (b); ++i)
#define rep2(i,a,b) for(int i = a; i <= (b); ++i)
#define rep3(i,a,b,c) for(int i = a; i <= (b); i+=c)
#define count_bits(x) __builtin_popcountll((x))
#define all(x) (x).begin(),(x).end()
#define siz(x) (int)(x).size()
#define forall(it,x) for(auto& it:(x))
using namespace __gnu_pbds;
using namespace std;
typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> ordered_set;
//mt19937 mt;void random_start(){mt.seed(chrono::time_point_cast<chrono::milliseconds>(chrono::high_resolution_clock::now()).time_since_epoch().count());}
//ll los(ll a, ll b) {return a + (mt() % (b-a+1));}
const int INF = 1e9+50;
const ll INF_L = 1e18+40;
const ll MOD = 1e9+7;

pll rotate(pll x)
{
    return {-x.ss,x.ff};
}

int dir[100001];
bool is[100001];
int n;
vector<pll> dirs = {{0,-1},{-1,0},{0,1},{1,0}};
pii parm[4][4];
pii parm2[4][4];
priority_queue<pll,vector<pll>,greater<pll>> pq;

struct line
{
    set<pll> non;
    unordered_map<int,ll> best_on;
    line()
    {
        non = {};
        best_on = {};
    }
    void add_on(ll poz, ll time)
    {
        ll l_poz = poz+time*2;
        auto it = non.lower_bound({l_poz,-1});
        if(it == non.end()) return;
        pq.push({((*it).ff-poz)/2,(*it).ss});
        if(best_on.find((*it).ss) == best_on.end()) best_on[(*it).ss] = poz;
        best_on[(*it).ss] = max(best_on[(*it).ss],poz);
    }
    void del_off(ll poz, int ind)
    {
        non.erase({poz,ind});
        if(best_on.find(ind) == best_on.end()) return;
        auto nxt = non.lower_bound({poz,-1});
        if(nxt == non.end()) return;
        pq.push({((*nxt).ff-best_on[ind])/2,(*nxt).ss});
        if(best_on.find((*nxt).ss) == best_on.end()) best_on[(*nxt).ss] = best_on[ind];
        best_on[(*nxt).ss] = max(best_on[(*nxt).ss],best_on[ind]);
    }
};

unordered_map<ll,line> str_[4][4];

ll get_ind(pll poz, pll type)
{
    return poz.ff*parm[type.ff][type.ss].ff + poz.ss*parm[type.ff][type.ss].ss;
}

ll get_ind2(pll poz, pll type)
{
    return poz.ff*parm2[type.ff][type.ss].ff + poz.ss*parm2[type.ff][type.ss].ss;
}

int solve(vector<pll>& points)
{
    rep(i,4) rep(j,4) str_[i][j] = {};
    rep(i,n)
    {
        is[i] = 0;
        pll it = points[i];
        if(it.ss-it.ff >= 0 && it.ss+it.ff <= 0) dir[i] = 3;
        else if(it.ss-it.ff <= -1 && it.ss+it.ff >= 1) dir[i] = 1;
        else if(it.ss > 0) dir[i] = 0;
        else dir[i] = 2;
    }
    rep(i,n) rep(k,4) if(k != dir[i]) str_[k][dir[i]][get_ind2(points[i],{k,dir[i]})].non.insert({get_ind(points[i],{k,dir[i]}),i});
    int ans = 0;
    pq = {};
    pq.push({0,0});
    while(!pq.empty())
    {
        pll t = pq.top();
        pq.pop();
        if(is[t.ss]) continue;
        is[t.ss] = 1;
        ans++;
        rep(i,4)
        {
            if(i == dir[t.ss]) continue;
            str_[dir[t.ss]][i][get_ind2(points[t.ss],{dir[t.ss],i})].add_on(get_ind(points[t.ss],{dir[t.ss],i}),t.ff);
            str_[i][dir[t.ss]][get_ind2(points[t.ss],{i,dir[t.ss]})].del_off(get_ind(points[t.ss],{i,dir[t.ss]}),t.ss);
        }
    }
    return ans;
}

int main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    //random_start();
    parm[0][1] = {1,-1};
    parm[0][2] = {0,-1};
    parm[0][3] = {-1,-1};
    parm[1][0] = {-1,1};
    parm[1][2] = {-1,-1};
    parm[1][3] = {-1,0};
    parm[2][0] = {0,1};
    parm[2][1] = {1,1};
    parm[2][3] = {-1,1};
    parm[3][0] = {1,1};
    parm[3][1] = {1,0};
    parm[3][2] = {1,-1};
    parm2[0][1] = {1,1};
    parm2[0][2] = {1,0};
    parm2[0][3] = {1,-1};
    parm2[1][0] = {1,1};
    parm2[1][2] = {1,-1};
    parm2[1][3] = {0,1};
    parm2[2][0] = {1,0};
    parm2[2][1] = {1,-1};
    parm2[2][3] = {1,1};
    parm2[3][0] = {1,-1};
    parm2[3][1] = {0,1};
    parm2[3][2] = {1,1};
    cin >> n;
    vector<pll> points(n);
    rep(i,n) cin >> points[i].ff >> points[i].ss;
    for(int i = n-1; i >= 0; i--)
    {
        points[i].ff -= points[0].ff;
        points[i].ss -= points[0].ss;
    }
    rep(i,n)
    {
        points[i].ff *= 2;
        points[i].ss *= 2;
    }
    int ans = 0;
    rep(i,4)
    {
        ans = max(ans,solve(points));
        forall(it,points) it = rotate(it);
    }
    cout << ans << "\n";
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...