Submission #1341188

#TimeUsernameProblemLanguageResultExecution timeMemory
1341188_as3adPermutation Game (APIO25_permgame)C++20
22 / 100
10 ms544 KiB
    #include "permgame.h"


    #ifdef Asaad
        #include "cp.h"
        #define debug(...) _dbg_many(#__VA_ARGS__, __VA_ARGS__)
        #define here cerr << "LINE " << __LINE__ << "\n"
    #else 
        #include <bits/stdc++.h>
        using namespace std;
        /*
        #include <ext/pb_ds/assoc_container.hpp>
        #include <ext/pb_ds/tree_policy.hpp>
        using namespace __gnu_pbds;
        template<class T>
        using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
        */
        #define debug(...) 
        #define here 
    #endif

    #define ll long long
    //#define int long long
    #define all(x) x.begin(), x.end()
    #define siz(x) ((int)x.size())
    #define yes cout << "YES\n"
    #define no cout << "NO\n"
    #define f first
    #define s second
    #define eb emplace_back
    #define pb push_back


    const int mod = 1e9+7;
    const int N = 200009;
    const long long inf = 1e18+12309138;
    double eps = 1e-9;


    int Alice(int m, int e, std::vector<int> u, std::vector<int> v, int n, std::vector<int> p) {
        int mod = m-1;
        vector<vector<int>> adj(m);    
        for (int i=0; i<e; i++) {
            adj[u[i]].pb(v[i]);
            adj[v[i]].pb(u[i]);
        }
        int cur = 0;
        for (int i=0; i<n; i++) cur+= (p[i]==i);

        bool ok = 1;
        bool c = 0;
        for (int i=0; i<m; i++) ok&=( siz(adj[i]) < 3 );
        if (!ok) return cur;
        int st = -1;
        for (int i=0; i<m; i++) if ( siz(adj[i]) == 1 ) st = i;
        if (st==-1) {
            st = 0;
            c =1;
        }
        vector<int> order, vis(n, 0), rr(m);
        vector<int> cr(n);
        vector<int> in(n), out(n);
        
        function<void(int)> dfs = [&] (int u) {
            vis[u]=1 ;
            order.pb(u);
            for (int& v : adj[u]) if (!vis[v]) dfs(v);
        };
        dfs(st);
        fill(all(vis), 0);
        for (int i=0; i<m; i++) rr[order[i]] = i;
        for (int i=0; i<n; i++) cr[p[i]] = i;
        for (int i=0; i<n; i++) if ( p[i] == i ) {
            in[i] = out[i] = i;
            vis[i] = 1;
        }
        map<int, int> mp;
        map<int, set<int>> mpp;
        vector<pair<int, int>> hi;
        vector<map<int, int>> bye(n+132); // bye[sum] -> {idx, st};
        int idx = 0;
        int sum = 0;
        for (int i=0; i<n; i++) {
            if (vis[i]) continue;
            int sz = 0;
            int x = p[i];
            while ( !vis[x] ) {
                debug(idx, x);
                vis[x] =1;
                sz++;
                mp[x] = idx;
                mpp[idx].insert(x);
                out[x] = p[x];
                in[p[x]] = x;
                x =p[x];

            }
            hi.eb( sz, x );
            bye[sz%mod][idx] = x;
            idx++;
            sum += sz;
        }

        auto update = [&] (int u, int v) {
            swap(in[u], in[v]);
            swap(cr[u], cr[v]);
            out[in[u]] = u;
            out[in[v]] = v;
            bool ou =0, ov = 0;
            if ( in[u] == out[u] && in[u]==u) ou = 1;
            if ( in[v] == out[v] && in[v]==v) ov = 1;
            if (ou&ov) {
                sum-= 2;
                bye[2%mod].erase(mp[u]);
                hi[mp[u]].f = 0;
                mpp[mp[u]].clear();
                return;
            }
            if (ou) {
                sum--;
                hi[mp[u]].s = v; 
                bye[hi[mp[u]].f%mod].erase(mp[u]); 
                bye[(mod+(--hi[mp[u]].f))%mod][mp[u]]=v; 
                mpp[mp[u]].erase(u);
                return;
            }
            if (ov) {
                sum--;
                hi[mp[v]].s = u; 
                bye[hi[mp[v]].f%mod].erase(mp[v]); 
                bye[(mod+(--hi[mp[v]].f))%mod][mp[v]]=u; 
                mpp[mp[v]].erase(v);
                return;
            }
            if ( mp[u] == mp[v] ) {
                int nu = 1, nv = 1;
                int uu = out[u], vv = out[v];
                while ( uu != u ) {
                    nu++;
                    uu = out[uu];
                }
                while (vv != v) {
                    nv++;
                    vv = out[vv];
                }
                if (nu != mod) swap(u, v);
                bye[hi[mp[v]].f%mod].erase(mp[v]);
                hi[mp[v]].f-= mod;
                hi[mp[v]].s = v;
                bye[hi[mp[v]].f%mod][mp[u]] = v;
                uu = out[uu];
                mpp[v].erase(uu);
                while (uu != u) {
                    mpp[v].erase(uu);
                    uu = out[uu];
                }


                return;
            }
            int ns = hi[mp[u]].f+hi[mp[v]].f;
            bye[hi[mp[u]].f%mod].erase(mp[u]);
            bye[hi[mp[v]].f%mod].erase(mp[v]);
            bye[ns%mod][mp[u]] = u;
            for (auto& x : mpp[mp[v]]) {
                mp[x] = mp[u];
                mpp[mp[u]].insert(x);
            }
            hi[mp[u]].f = ns;
            hi[mp[u]].s = u;

        };
        vector<int> ans;
        vector<int> bb(m);
        auto bob = [&] () {
            for (int i=0; i<m; i++) bb[order[i]] = cr[ans[i]];
            int x = Bob(bb);
            int uu = rr[u[x]];
            int vv = rr[v[x]];
            update(ans[uu], ans[vv]);
        };
        int op;
        if (e==m-1) {
            op = max(cur, n-mod );
            if (m==2) op = n;
            while (sum>=m) {
                ans.clear();
                for (auto& a : bye) {
                    if (siz(ans)>=m) break;
                    for (auto& [id, st] : a) {
                        if ( siz(ans)>=m ) break;
                        int tmp = out[st];
                        ans.pb(st);
                        while (tmp != st) {
                            ans.pb(tmp);
                            tmp = out[tmp];
                            if (siz(ans)>=m) break;
                        }
                    }
                }
                bob();
            }
            return op;
        }

        
        
        return op;



    }
#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...