Submission #539749

#TimeUsernameProblemLanguageResultExecution timeMemory
539749Eug1enaRoller Coaster Railroad (IOI16_railroad)C++14
30 / 100
254 ms20944 KiB
#include <bits/stdc++.h>
using namespace std;
using lint = long long;
#define rep(i, n) for(int i = 0; i < int(n); i++)
#define rep2(i, l, n) for(int i = int(l); i < int(n); i++)
#define repr(i, n) for(int i = int(n) - 1; i >= 0; i--)
#define all(x) (x).begin(), (x).end()
inline int has(lint x, int k){ return (x >> k) & 1; };

string to_string(vector<int> v){
    string str;
    for(lint x: v){
        str += to_string(x);
        str += " ";
    }
    return str;
}

struct UnionFind{
    int sz;
    vector<int> par;

    UnionFind(int n){
        sz = n;
        par.resize(n, -1);
    }

    int find(int k){
        if(par[k] == -1) return k;
        return par[k] = find(par[k]);
    }

    void unite(int a, int b){
        a = find(a), b = find(b);
        if(a == b) return;

        par[a] = b;
    }
};

lint plan_roller_coaster(vector<int> s_in, vector<int> t_in){
    int n = int(s_in.size());
    n++;

    int a[n], b[n];
    rep(i, n - 1){
        a[i] = s_in[i];
        b[i] = t_in[i];
    }
    a[n - 1] = 1e9 + 100;
    b[n - 1] = 1;

    vector<int> nums;
    rep(i, n){
        nums.push_back(a[i]);
        nums.push_back(b[i]);
    }
    sort(all(nums));
    nums.erase(unique(all(nums)), nums.end());

    int sz = int(nums.size());
    vector<int> deg(sz, 0);
    UnionFind uf(sz);
    rep(i, n){
        int a_idx = int(lower_bound(all(nums), a[i]) - nums.begin());
        int b_idx = int(lower_bound(all(nums), b[i]) - nums.begin());

        deg[a_idx]--;
        deg[b_idx]++;
        
        uf.unite(a_idx, b_idx);
    }

    int sum = deg[0];
    vector<int> big_light(sz - 1);
    rep(i, sz - 1){
        big_light[i] = sum;

        sum += deg[i + 1];
    }

    // cout << to_string(deg) << endl;
    // cout << to_string(big_light) << endl;

    rep(i, sz - 1){
        if(big_light[i] < 0){
            return 1;
        }
    }

    rep(i, sz - 1){
        if(big_light[i] > 0){
            uf.unite(i, i + 1);
        }
    }

    set<int> roots;
    rep(i, sz){
        roots.insert(uf.find(i));
    }
    if(roots.size() > 1) return 1;

    return 0;
}


int n;
lint a[30], b[30];
lint dp[20][1 << 16];
 
lint play(int at, int bit){
    if(bit == (1 << n) - 1){
        return 0;
    }
    if(dp[at][bit] != -1) return dp[at][bit];
 
    lint ans = 1e18;
    rep(to, n){
        if(has(bit, to)) continue;
 
        lint res = max(0ll, b[at] - a[to]);
        res += play(to, bit | (1 << to));
 
        ans = min(ans, res);
    }
 
    return dp[at][bit] = ans;
}
 
lint plan_roller_coaster_CORRECT(vector<int> s_in, vector<int> t_in){
    n = int(s_in.size());
    assert(n <= 16);
 
    rep(i, n){
        a[i] = s_in[i];
        b[i] = t_in[i];
    }
    b[n] = 1;
 
    memset(dp, -1, sizeof(dp));
    return play(n, 0);
}


// int main(){
//     // vector<int> s{1, 4, 5, 6};
//     // vector<int> t{7, 3, 8, 6};
//     // cout << plan_roller_coaster(s, t) << endl; // 3


//     // vector<int> s{1, 5, 3};
//     // vector<int> t{4, 2, 6};
//     // cout << plan_roller_coaster(s, t) << endl; // 0

//     vector<int> s{2, 2};
//     vector<int> t{3, 3};
//     cout << plan_roller_coaster(s, t) << endl; // 1

//     // random_device rnd;
//     // rep(_, 1e5){
//     //     int MAX_N = 2;
//     //     int MAX_A = 3;

//     //     int n = rnd() % (MAX_N - 1) + 2;
//     //     vector<int> s, t;
//     //     rep(i, n){
//     //         s.push_back(rnd() % MAX_A + 1);
//     //         t.push_back(rnd() % MAX_A + 1);
//     //     }
        
//     //     int ans = plan_roller_coaster(s, t);
//     //     int ans_CORRECT = !!plan_roller_coaster_CORRECT(s, t);
//     //     if(ans != ans_CORRECT){
            
//     //         cout << n << endl;
//     //         rep(i, n) cout << s[i] << " ";
//     //         cout << endl;
//     //         rep(i, n) cout << t[i] << " ";
//     //         cout << endl;
//     //         cout << "ans: " << ans << endl;
//     //         cout << "ans_CORRECT: " << ans_CORRECT << endl;
//     //         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...