Submission #99647

#TimeUsernameProblemLanguageResultExecution timeMemory
99647square1001Amusement Park (JOI17_amusement_park)C++14
100 / 100
280 ms26708 KiB
#include "Joi.h" #include <vector> #include <algorithm> #include <functional> #include <unordered_map> using namespace std; const int bits = 60; struct edge { int a, b; edge() : a(-1), b(-1) {}; edge(int a_, int b_) : a(a_), b(b_) {}; }; pair<vector<vector<edge> >, vector<int> > generate(int N, vector<vector<int> > G) { vector<int> d(N, -1), par(N, -1); function<void(int, int)> find_depth = [&](int pos, int pre) { d[pos] = (pre == -1 ? 0 : d[pre] + 1); par[pos] = pre; for(int i : G[pos]) { if(i != pre) find_depth(i, pos); } }; find_depth(0, -1); vector<int> ord(N); for(int i = 0; i < N; ++i) ord[i] = i; sort(ord.begin(), ord.end(), [&](int i, int j) { return d[i] < d[j]; }); vector<int> inv(N); for(int i = 0; i < N; ++i) inv[ord[i]] = i; vector<edge> ini; for(int i = 0; i < bits; ++i) { for(int j : G[ord[i]]) { if(inv[j] < bits && ord[i] < j) { ini.push_back(edge(ord[i], j)); } } } vector<vector<edge> > ans(N); vector<int> id(N, -1); for(int i = 0; i < bits; ++i) { ans[ord[i]] = ini; id[ord[i]] = i; } for(int i = bits; i < N; ++i) { unordered_map<int, int> tbl; for(edge j : ans[par[ord[i]]]) { ++tbl[j.a]; ++tbl[j.b]; } int eraser = -1; for(pair<int, int> j : tbl) { if(j.second == 1 && j.first != par[ord[i]]) { eraser = j.first; } } for(edge j : ans[par[ord[i]]]) { if(j.a != eraser && j.b != eraser) { ans[ord[i]].push_back(j); } } ans[ord[i]].push_back(edge(ord[i], par[ord[i]])); id[ord[i]] = id[eraser]; } return make_pair(ans, id); } vector<vector<int> > get_spanning_tree(int N, vector<vector<int> > G) { vector<vector<int> > ans(N); vector<bool> vis(N); function<void(int)> dfs = [&](int pos) { vis[pos] = true; for(int i : G[pos]) { if(!vis[i]) { ans[pos].push_back(i); ans[i].push_back(pos); dfs(i); } } }; dfs(0); return ans; } void Joi(int N, int M, int A[], int B[], long long X, int T) { vector<vector<int> > G(N); for(int i = 0; i < M; ++i) { G[A[i]].push_back(B[i]); G[B[i]].push_back(A[i]); } G = get_spanning_tree(N, G); pair<vector<vector<edge> >, vector<int> > res = generate(N, G); for(int i = 0; i < N; ++i) { int val = (X >> res.second[i]) & 1; MessageBoard(i, val); } }
#include "Ioi.h" #include <vector> #include <algorithm> #include <functional> #include <unordered_map> using namespace std; const int bits = 60; struct edge { int a, b; edge() : a(-1), b(-1) {}; edge(int a_, int b_) : a(a_), b(b_) {}; }; pair<vector<vector<edge> >, vector<int> > generate2(int N, vector<vector<int> > G) { vector<int> d(N, -1), par(N, -1); function<void(int, int)> find_depth = [&](int pos, int pre) { d[pos] = (pre == -1 ? 0 : d[pre] + 1); par[pos] = pre; for(int i : G[pos]) { if(i != pre) find_depth(i, pos); } }; find_depth(0, -1); vector<int> ord(N); for(int i = 0; i < N; ++i) ord[i] = i; sort(ord.begin(), ord.end(), [&](int i, int j) { return d[i] < d[j]; }); vector<int> inv(N); for(int i = 0; i < N; ++i) inv[ord[i]] = i; vector<edge> ini; for(int i = 0; i < bits; ++i) { for(int j : G[ord[i]]) { if(inv[j] < bits && ord[i] < j) { ini.push_back(edge(ord[i], j)); } } } vector<vector<edge> > ans(N); vector<int> id(N, -1); for(int i = 0; i < bits; ++i) { ans[ord[i]] = ini; id[ord[i]] = i; } for(int i = bits; i < N; ++i) { unordered_map<int, int> tbl; for(edge j : ans[par[ord[i]]]) { ++tbl[j.a]; ++tbl[j.b]; } int eraser = -1; for(pair<int, int> j : tbl) { if(j.second == 1 && j.first != par[ord[i]]) { eraser = j.first; } } for(edge j : ans[par[ord[i]]]) { if(j.a != eraser && j.b != eraser) { ans[ord[i]].push_back(j); } } ans[ord[i]].push_back(edge(ord[i], par[ord[i]])); id[ord[i]] = id[eraser]; } return make_pair(ans, id); } vector<vector<int> > get_spanning_tree2(int N, vector<vector<int> > G) { vector<vector<int> > ans(N); vector<bool> vis(N); function<void(int)> dfs = [&](int pos) { vis[pos] = true; for(int i : G[pos]) { if(!vis[i]) { ans[pos].push_back(i); ans[i].push_back(pos); dfs(i); } } }; dfs(0); return ans; } long long Ioi(int N, int M, int A[], int B[], int P, int V, int T) { vector<vector<int> > G(N); for(int i = 0; i < M; ++i) { G[A[i]].push_back(B[i]); G[B[i]].push_back(A[i]); } G = get_spanning_tree2(N, G); pair<vector<vector<edge> >, vector<int> > res = generate2(N, G); vector<int> id = res.second; vector<edge> subgraph = res.first[P]; vector<bool> vis(N); vector<int> route; function<void(int)> dfs = [&](int pos) { vis[pos] = true; route.push_back(pos); for(edge e : subgraph) { if(e.a == pos && !vis[e.b]) dfs(e.b); if(e.b == pos && !vis[e.a]) dfs(e.a); route.push_back(pos); } }; dfs(P); route.erase(unique(route.begin(), route.end()), route.end()); long long ans = (long long)(V) << id[P]; for(int i = 1; i < route.size(); ++i) { ans |= (long long)(Move(route[i])) << id[route[i]]; } return ans; }

Compilation message (stderr)

Ioi.cpp: In function 'long long int Ioi(int, int, int*, int*, int, int, int)':
Ioi.cpp:104:19: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
  for(int i = 1; i < route.size(); ++i) {
                 ~~^~~~~~~~~~~~~~
#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...