Submission #502392

#TimeUsernameProblemLanguageResultExecution timeMemory
502392VictorSwapping Cities (APIO20_swap)C++17
100 / 100
450 ms23020 KiB
    // #pragma GCC target ("avx,avx2,fma")
    // #pragma GCC optimize ("Ofast,inline") // O1 - O2 - O3 - Os - Ofast
    // #pragma GCC optimize ("unroll-loops")
    #include "swap.h"
     
    #include <bits/stdc++.h>
     
    using namespace std;
     
    #define rep(i, a, b) for (int i = (a); i < (b); ++i)
    #define per(i, a, b) for (int i = (b - 1); i >= (a); --i)
    #define trav(a, x) for (auto &a : x)
     
    #define all(x) x.begin(), x.end()
    #define sz(x) x.size()
    #define pb push_back
    #define debug(x) cout << #x << " = " << x << endl
     
    #define umap unordered_map
    #define uset unordered_set
     
    typedef pair<int, int> ii;
    typedef pair<int, ii> iii;
    typedef vector<int> vi;
    typedef vector<ii> vii;
    typedef vector<vi> vvi;
     
    typedef long long ll;
    typedef pair<ll, ll> pll;
    typedef vector<ll> vll;
    typedef vector<pll> vpll;
     
    const int INF = 1'000'000'007;
     
    struct ufds_rollback {
        vector<vii>p;
        vi rank,max_deg,possible,deg;
        vector<bool>cycle;
        
        ufds_rollback(int n) {
            deg.assign(n,0);
            rank.assign(n,0);
            cycle.assign(n,0);
            max_deg.assign(n,0);
            possible.assign(n,INF);
     
            p.resize(n);
            rep(i,0,n)p[i].emplace_back(0,i);
        }
     
        int find(int i,const int &mx) {
            auto it=upper_bound(all(p[i]),ii(mx,INF));
            --it;
            //cout<<"i = "<<i<<" mx = "<<mx<<" val = "<<it->first<<" p = "<<it->second<<endl;
            if(it->second==i)return i;
            else return find(it->second,mx);
            return 0;
        }
     
        void union_set(int i,int j,int val) {
            int u=find(i,val);
            int v=find(j,val);
            if(u==v) {
                cycle[u]=1;
                possible[u]=min(possible[u],val);
                return;
            }
     
            ++deg[i];
            ++deg[j];
            max_deg[u]=max(max_deg[u],deg[i]);
            max_deg[v]=max(max_deg[v],deg[j]);
     
            if(rank[u]<rank[v])swap(u,v);
          	if(rank[u]==rank[v])++rank[u];
            if(p[v].back().first==val)p[v].pop_back();
            p[v].emplace_back(val,u);
            max_deg[u]=max(max_deg[u],max_deg[v]);
            
            if(possible[v]!=INF||max_deg[u]>=3) possible[u]=min(possible[u],val);
        }
    };
     
    ufds_rollback ufds(100001);
    vector<iii> edges;
    int n,m;
     
    void init(int N, int M, std::vector<int> U, std::vector<int> V, std::vector<int> W) {
        n=N;
        m=M;
        rep(i,0,m) edges.pb({W[i],{U[i],V[i]}});
        sort(all(edges));
        //rep(i,0,n) {
        //    auto it=ufds.p[i].begin();
        //    cout<<sz(ufds.p[i])<<' '<<it->first<<' '<<it->second<<' ';
        //    ufds.find(i,0);
        //}
        trav(edge,edges) {
            int u,v,w;
            w=edge.first;
            tie(u,v)=edge.second;
            ufds.union_set(u,v,w);
            //cout<<"u = "<<u<<" v = "<<v<<" w = "<<w<<endl;
        }
        edges.pb({-1,{0,0}});
    }
     
    int getMinimumFuelCapacity(int X, int Y) {
        int u=X,v=Y;
        int lo=0,hi=m;
        while(lo!=hi) {
            int mid=(lo+hi)/2;
            int w=edges[mid].first;
            int p=ufds.find(u,w);
            if(p==ufds.find(v,w)&&ufds.possible[p]<=w) hi=mid;
            else lo=mid+1;
        }
        return edges[lo].first;
    }
     
    /*
    int main() {
        int N, M;
        assert(2 == scanf("%d %d", &N, &M));
     
        std::vector<int> U(M), V(M), W(M);
        for (int i = 0; i < M; ++i) {
            assert(3 == scanf("%d %d %d", &U[i], &V[i], &W[i]));
        }
     
        int Q;
        assert(1 == scanf("%d", &Q));
     
        std::vector<int> X(Q), Y(Q);
        for (int i = 0; i < Q; ++i) {
            assert(2 == scanf("%d %d", &X[i], &Y[i]));
        }
     
        init(N, M, U, V, W);
     
        std::vector<int> minimum_fuel_capacities(Q);
        for (int i = 0; i < Q; ++i) {
            minimum_fuel_capacities[i] = getMinimumFuelCapacity(X[i], Y[i]);
        }
     
        for (int i = 0; i < Q; ++i) {
            printf("%d\n", minimum_fuel_capacities[i]);
        }
     
        return 0;
    }*/
#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...