제출 #1254500

#제출 시각아이디문제언어결과실행 시간메모리
1254500nvc2k8Passport (JOI23_passport)C++20
100 / 100
283 ms18528 KiB
#include <bits/stdc++.h>
#define TASK "TASK"
#define endl '\n'
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define BIT(i,x) (((i)>>(x))&1)
#define FOR(i,a,b) for(int i = (a); i<=(b); i++)
#define FORD(i,a,b) for(int i = (a); i>=(b); i--)
#define all(C) C.begin(), C.end()
using namespace std;
using ll = long long;
using pii = pair<int,int>;
const int INT_LIM = 2147483647;
const ll LL_LIM = 9223372036854775807;
template <typename X> bool minimize(X &x, const X &y) {if (x>y){x = y; return true;}return false;}
template <typename X> bool maximize(X &x, const X &y) {if (x<y){x = y; return true;}return false;}
///------------------------------------------///
int CNT = 0, CNT2 = 0;
int n;
struct SegmentTree{
    int leaf[200005], p[200005], q[200005];
    int f[200005];
    pii T[800005];

    void build(int id, int l, int r, pair<pii,int> val[200005])
    {
        if (l==r)
        {
            leaf[l] = id;
            T[id] = val[l].fi;
            p[l] = val[l].se;
            q[p[l]] = l;
            f[l] = val[l].fi.fi;
            return;
        }
        int mid = (l+r)>>1;
        build(id*2, l, mid, val);
        build(id*2+1, mid+1, r, val);
        T[id].fi = min(T[id*2].fi, T[id*2+1].fi);
        T[id].se = max(T[id*2].se, T[id*2+1].se);
    }
    void update(int u)
    {
        u = q[u];
        T[leaf[u]] = mp(INT_LIM, -INT_LIM); CNT2++;
        for (int id = leaf[u]>>1; id>0; id>>=1)
        {
            CNT2++;
            T[id].fi = min(T[id*2].fi, T[id*2+1].fi);
            T[id].se = max(T[id*2].se, T[id*2+1].se);
        }
    }
    void walk(int id, int l, int r, int x, vector<int> &ret)
    {
//        CNT++;
        if (T[id].fi>x || T[id].se<x) return;
        if (l==r)
        {
            ret.pb(p[l]); return;
        }
        int mid = (l+r)>>1;
        walk(id*2, l, mid, x, ret);
        walk(id*2+1, mid+1, r, x, ret);
    }

    void query(int id, int l, int r, int u, int v, int x, vector<int> &ret)
    {
//        CNT++;
        if (l>v || r<u) return;
        if (l>=u && r<=v)
        {
            walk(id, l, r, x, ret); return;
        }
        int mid = (l+r)>>1;
        query(id*2, l, mid, u, v, x, ret);
        query(id*2+1, mid+1, r, u, v, x, ret);
    }

    void process(int x, vector<int> &ret)
    {
        int l = 1, r = n, R = -1;
        while(l<=r)
        {
            int mid = (l+r)>>1;
            if (f[mid]<=x)
            {
                R = mid;
                l = mid+1;
            }
            else r = mid-1;
        }
        if (R==-1) return;
        query(1, 1, n, 1, R, x, ret);
    }
} tree;

int q;
pair<pii,int> a[200005];
int dist[2][200005];
int f[200005];

void inp()
{
    cin >> n;
    FOR(i, 1, n)
    {
        cin >> a[i].fi.fi >> a[i].fi.se;
        a[i].se = i;
    }
    sort(a+1, a+1+n);
    cin >> q;
}

void dijkstra(int source, int dist[200005])
{
    tree.build(1, 1, n, a);
    priority_queue<pii, vector<pii>, greater<pii> > q;

    if (source)
    {
        FOR(i, 1, n) dist[i] = INT_LIM;
        dist[source] = 0; q.push(mp(0, source));
    }
    else
    {
        FOR(i, 1, n) if (dist[i]!=INT_LIM)
            q.push(mp(dist[i], i));
    }

    while (!q.empty())
    {
        int u = q.top().se, d = q.top().fi;
        q.pop();
        if (dist[u]<d) continue;
        vector<int> adj;
        tree.process(u, adj);
        for (auto v:adj)
        {
            tree.update(v);
            if (minimize(dist[v], d+1)) q.push(mp(d+1, v));
        }
    }
}

void solve()
{
    dijkstra(1, dist[0]);
//    cerr << CNT << ' ' << CNT2 << endl;
    dijkstra(n, dist[1]);
//    cerr << CNT << ' ' << CNT2 << endl;
    FOR(i, 1, n)
    {
        if (dist[0][i]!=INT_LIM && dist[1][i]!=INT_LIM)
        {
            f[i] = dist[0][i]+dist[1][i];
            if (i!=1 && i!=n) f[i]--;
        }
        else f[i] = INT_LIM;
    }
    dijkstra(0, f);

    FOR(i, 1, q)
    {
        int x;
        cin >> x;
        if (f[x]==INT_LIM) cout << -1 << endl;
        else cout << f[x] << endl;
    }
//    cerr << CNT << ' ' << CNT2 << endl;
}

signed main()
{
    ///--------------------------///
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    if (fopen(TASK".INP","r")!=NULL)
    {
        freopen(TASK".INP","r",stdin);
        freopen(TASK".OUT","w",stdout);
    }
    ///--------------------------///

    int NTEST = 1;
    bool codeforces = 0;
    if (codeforces) cin >> NTEST;

    while (NTEST--)
    {
        inp();
        solve();
    }

    return 0;
}

///------------------------------------------///

컴파일 시 표준 에러 (stderr) 메시지

passport.cpp: In function 'int main()':
passport.cpp:180:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  180 |         freopen(TASK".INP","r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
passport.cpp:181:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  181 |         freopen(TASK".OUT","w",stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
#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...