Submission #1047051

#TimeUsernameProblemLanguageResultExecution timeMemory
1047051ssenseSwapping Cities (APIO20_swap)C++14
100 / 100
152 ms85700 KiB
#include <iostream> #include "swap.h" #include <algorithm> #include <vector> #include <array> #include <set> #include <map> #include <queue> #include <stack> #include <list> #include <chrono> #include <random> #include <cstdlib> #include <cmath> #include <ctime> #include <cstring> #include <iomanip> #include <bitset> #include <limits.h> #include <cassert> #define fr first #define sc second using namespace std; // #define int long long const int N = 500005; int dsu[N], par[23][N], valid[N], sz[N], zero[N], one[N], two[N], deg[N], val[N], depth[N]; int new_vertex; vector<int> adj[N]; int find(int a) { if(dsu[a] == a) { return a; } return dsu[a] = find(dsu[a]); } void add_edge(int a, int b, int w) { int ca = find(a); int cb = find(b); if(ca == cb) { dsu[new_vertex] = new_vertex; par[0][ca] = new_vertex; dsu[ca] = new_vertex; adj[new_vertex].push_back(ca); val[new_vertex] = w; if(valid[ca]) { valid[new_vertex] = 1; } sz[new_vertex] = sz[ca]; zero[new_vertex] = zero[ca]; one[new_vertex] = one[ca]; two[new_vertex] = two[ca]; if(deg[a] == 2 || deg[b] == 2) { valid[new_vertex] = 1; new_vertex++; return; } if(deg[a] == 0) { deg[a]++; zero[new_vertex]--; one[new_vertex]++; } else if(deg[a] == 1) { deg[a]++; one[new_vertex]--; two[new_vertex]++; } if(deg[b] == 0) { deg[b]++; zero[new_vertex]--; one[new_vertex]++; } else if(deg[b] == 1) { deg[b]++; one[new_vertex]--; two[new_vertex]++; } if(two[new_vertex] == sz[new_vertex]) { valid[new_vertex] = 1; } new_vertex++; return; } dsu[new_vertex] = new_vertex; dsu[ca] = new_vertex; dsu[cb] = new_vertex; par[0][ca] = new_vertex; par[0][cb] = new_vertex; adj[new_vertex].push_back(ca); adj[new_vertex].push_back(cb); val[new_vertex] = w; if(valid[ca] || valid[cb]) { valid[new_vertex] = 1; } else { if(deg[a] == 2 || deg[b] == 2) { valid[new_vertex] = 1; new_vertex++; return; } sz[new_vertex] = sz[ca]+sz[cb]; zero[new_vertex] = zero[ca]+zero[cb]; one[new_vertex] = one[ca]+one[cb]; two[new_vertex] = two[ca]+two[cb]; if(deg[a] == 0) { deg[a]++; zero[new_vertex]--; one[new_vertex]++; } else if(deg[a] == 1) { deg[a]++; one[new_vertex]--; two[new_vertex]++; } if(deg[b] == 0) { deg[b]++; zero[new_vertex]--; one[new_vertex]++; } else if(deg[b] == 1) { deg[b]++; one[new_vertex]--; two[new_vertex]++; } if(two[new_vertex] == sz[new_vertex]) { valid[new_vertex] = 1; } } new_vertex++; } void dfs(int u) { for(auto v : adj[u]) { depth[v] = depth[u]+1; dfs(v); } } int jump(int a, int len) { for(int i = 0; i <= 19; i++) { if((len&(1<<i)) != 0) { a = par[i][a]; } } return a; } int lca_v(int a, int b) { // cout << "FINDING LCA: " << a << " " << b << endl; int lca; if(depth[a] < depth[b]) { swap(a, b); } a = jump(a, depth[a]-depth[b]); if(a == b){lca = a;} else { // cout << "BEFORE ENTERING: " << a << " " << b << endl; for(int i = 19; i >= 0; i--) { if(par[i][a] != par[i][b]) { a = par[i][a]; b = par[i][b]; } } lca = par[0][a]; } // cout << "LCA FOUND BEFORE VALID: " << lca << endl; if(valid[lca]) { return lca; } for(int i = 19; i >= 0; i--) { if(valid[par[i][lca]] == 0) { lca = par[i][lca]; } } lca = par[0][lca]; return lca; } void init(int n, int m, vector<int> u, vector<int> v, vector<int> w) { for(int i = 1; i <= n; i++) { zero[i] = 1; sz[i] = 1; dsu[i] = i; } new_vertex = n+1; vector<pair<int, int> > s; for(int i = 0; i < m; i++) { s.push_back(make_pair(w[i], i)); } sort(s.begin(), s.end()); for(int i = 0; i < m; i++) { //cout << "ADDING EDGE: " << u[s[i].sc]+1 << " " << v[s[i].sc]+1 << " " << s[i].fr << endl; add_edge(u[s[i].sc]+1, v[s[i].sc]+1, s[i].fr); } // for(int i = 0; i < new_vertex; i++) // { // cout << "VALID[" << i << "] = " << valid[i] << endl; // } if(valid[new_vertex-1]) { valid[0] = 1; } depth[0] = -1; dfs(new_vertex-1); // for(int i = 0; i < new_vertex; i++) // { // cout << "Depth[" << i << "] = " << depth[i] << endl; // } for(int i = 1; i <= 19; i++) { for(int j = 1; j < new_vertex; j++) { par[i][j] = par[i-1][par[i-1][j]]; } } // cout << new_vertex << endl; } int getMinimumFuelCapacity(int x, int y) { x++; y++; int bruh = lca_v(x, y); if(bruh == 0) { return -1; } else { return val[bruh]; } } // int32_t main() // { // ios_base::sync_with_stdio(false);cin.tie(0); // int n, m, q; // cin >> n >> m; // vector<int> u(m), v(m), w(m); // for(int i = 0; i < m; i++) // { // cin >> u[i]; // } // for(int i = 0; i < m; i++) // { // cin >> v[i]; // } // for(int i = 0; i < m; i++) // { // cin >> w[i]; // } // init(n, m, u, v, w); // cin >> q; // for(int i = 0; i < q; i++) // { // int x, y; // cin >> x >> y; // cout << getMinimumFuelCapacity(x, y) << endl; // } // } /* 5 6 0 0 1 1 1 2 1 2 2 3 4 3 4 4 1 2 10 3 3 1 2 2 4 0 1 */ /* #include <iostream> #include <algorithm> #include <vector> #include <array> #include <set> #include <map> #include <queue> #include <stack> #include <list> #include <chrono> #include <random> #include <cstdlib> #include <cmath> #include <ctime> #include <cstring> #include <iomanip> #include <bitset> #include <cassert> */
#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...