Submission #966380

#TimeUsernameProblemLanguageResultExecution timeMemory
966380anangoRoller Coaster Railroad (IOI16_railroad)C++17
100 / 100
718 ms105756 KiB
#include "railroad.h" #include <bits/stdc++.h> using namespace std; #define int long long class DSU { private: int n; vector<int> parent; vector<int> rank; public: DSU(int siz) { n=siz; parent=vector<int>(n,-1); rank=vector<int>(n,0); for (int i=0; i<n; i++) { parent[i]=i; } } int find(int node) { if (node==parent[node]) { return node; } return parent[node] = find(parent[node]); } void link(int u, int v) { u=find(u); v=find(v); if (u==v) { return; } if (rank[u]<rank[v]) { swap(u,v); } if (rank[u]==rank[v]) { rank[u]++; } parent[v]=u; return; } vector<int> getpar() { for (int i=0; i<n; i++) { find(i); } return parent; } }; int plan_roller_coaster(vector<int32_t> s, vector<int32_t> t) { int n = (int) s.size(); int INF=1000000007; set<int> crucial; for (int i=0; i<n; i++) { crucial.insert(s[i]); crucial.insert(t[i]); } crucial.insert(1); crucial.insert(INF); int cr = crucial.size(); map<int,int> rev; vector<int> cval; for (auto i:crucial) { cval.push_back(i); //coordinate compression } // cout << "COMPRESSION" << endl; for (int i=0; i<cr; i++) { rev[cval[i]] = i; // cout << rev[cval[i]] <<" " << cval[i] << endl; } for (int i=0; i<n; i++) { s[i]=rev[s[i]]; t[i]=rev[t[i]]; //sorry for polluting the arrays given, check this does not cause a bug in the orange juice } // cout << "OR ARRAYS" << endl; for (int i=0; i<n; i++) { // cout << s[i] <<" " << t[i] << endl; } vector<int> deltadiffarray(cr+1,0); //sum of blubberisation coefficients up to cr[i], each is cr[i] to cr[i+1] delta for (int i=0; i<n; i++) { deltadiffarray[s[i]]++; deltadiffarray[t[i]]--; // cout << "+"<<s[i] <<" -"<< t[i] << endl; } deltadiffarray[0]--; deltadiffarray[cr-1]++; //make the req val 1 vector<int> deltas(cr,0); int su=0; int operations = 0; for (int i=0; i<cr-1; i++) { su+=deltadiffarray[i]; deltas[i] = su; if (deltas[i]>0) { operations += deltas[i]*(cval[i+1] - cval[i]); } } // cout << "DELTA DIFFS" << endl; for (int i=0; i<cr; i++) { // cout << i <<" " << deltadiffarray[i] << endl; } // cout << "DELTAS" << endl; for (int i=0; i<cr; i++) { // cout << i <<" " << deltas[i] << endl; } DSU comp(cr); for (int i=0; i<n; i++) { comp.link(s[i],t[i]); // cout << "linking " << s[i] <<" " << t[i] << endl; } for (int i=0; i<cr-1; i++) { if (deltas[i]!=0) { comp.link(i,i+1); } } vector<int> components = comp.getpar(); // cout << "COMPONENTS" << endl; for (int i=0; i<cr; i++) { // cout << i <<" " << components[i] << endl; } set<int> comps; for (auto i:components) { comps.insert(i); } vector<int> cvec; vector<int> revvec(400000, -1); for (auto i:comps) { cvec.push_back(i); } int tau = cvec.size(); for (int i=0; i<tau; i++) { revvec[cvec[i]] = i; } vector<vector<pair<int,int>>> adjlist(tau); vector<vector<int>> edges; for (int i=0; i<cr-1; i++) { if (components[i] == components[i+1]) { continue; } int dist = cval[i+1] - cval[i]; adjlist[revvec[components[i]]].push_back({revvec[components[i+1]],dist}); adjlist[revvec[components[i+1]]].push_back({revvec[components[i]],dist}); edges.push_back({revvec[components[i]],revvec[components[i+1]],dist}); } //use the method of Kruskal, reusing the DSU, to find the component sum of min span tree DSU K(tau); sort(edges.begin(), edges.end(), [=](const vector<int> &v1, const vector<int> &v2) { return v1[2] < v2[2]; }); int cost=0; for (vector<int> edge:edges) { int u,v,w; u=edge[0]; v=edge[1]; w=edge[2]; if (K.find(u)==K.find(v)) { continue; } K.link(u,v); cost+=w; } return operations+cost; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...