제출 #1032300

#제출 시각아이디문제언어결과실행 시간메모리
1032300Tonyl즐거운 행로 (APIO20_fun)C++17
47 / 100
165 ms16460 KiB
#include "fun.h" #include <bits/stdc++.h> using namespace std; using vi = vector<int>; using pi = pair<int,int>; using ll = long long; #define REP(i,n) for (int i = 0; i < n; i++) #define trav(a,x) for (auto &a : x) #define all(x) (x).begin(), (x).end() #define D(x) cerr << #x << ": " << x << endl; int n, q; map<pi, int> dists; int ask_dist(int a, int b) { if (a > b) swap(a,b); if (!dists.count({a,b})) dists[{a,b}] = hoursRequired(a,b); return dists[{a,b}]; } //attractionsBehind std::vector<int> createFunTour500(int N, int Q) { n = N; q = Q; vector<pair<int,pi>> alld(n*n); REP(i,n) { REP(j,n) alld[i*n+j] = {ask_dist(i,j), {i,j}}; } sort(all(alld)); vector<bool> done(n, 0); int s = alld.back().second.first; vi ans = {s}; done[s] = 1; //D(s); while (--n) { int best = s; REP(i,N) { if (done[i]) continue; if (ask_dist(s, best) < ask_dist(s, i)) best = i; } assert(s != best); s = best; //D(s); done[s] = 1; ans.push_back(s); } return ans; } struct Node { bool exists = false; int leftd = 0, rightd = 0; }; const int MAX_N = 400004; Node tree[MAX_N]; void update(int i) { tree[i].leftd = 0; if (tree[2*i].exists) tree[i].leftd = max(tree[2*i].leftd, tree[2*i].rightd) + 1; tree[i].rightd = 0; if (tree[2*i+1].exists) tree[i].rightd = max(tree[2*i+1].leftd, tree[2*i+1].rightd) + 1; if (i > 1) update(i/2); } void consume(int i) { assert(tree[i].exists); tree[i].exists = 0; update(i); } int sink(int i) { if (tree[i].leftd > tree[i].rightd) return sink(2*i); else if (tree[i].rightd == 0) return i; else return sink(2*i+1); } int find_best(int i) { int best = 2*i+1; bool just_top = false; if (tree[i].leftd >= tree[i].rightd) best = 2*i; int maxs = max(tree[i].leftd, tree[i].rightd); int bonus = 0; while (i > 1) { bool fr = i%2; i/=2; bonus++; if (!tree[i].exists) break; if (bonus > maxs) { best = i; maxs = bonus; just_top = 1; } if (fr) { if (bonus+tree[i].leftd > maxs) { best = 2*i; maxs = bonus+tree[i].leftd; just_top = 0; } } else { if (bonus+tree[i].rightd > maxs) { best = 2*i+1; maxs = bonus+tree[i].rightd; just_top = 0; } } } if (just_top) return best; else return sink(best); } std::vector<int> createFunTour(int N, int Q) { if (N <= 500) return createFunTour500(N, Q); n = N; q = Q; n++; REP(i,n) tree[i].exists = 1; REP(i,n) update(i); int s = n-1; vi ans = {s}; consume(s); //D(s); while (--N) { s = find_best(s); //D(s); consume(s); ans.push_back(s); } REP(i,n) ans[i]--; return ans; }
#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...