Submission #805482

#TimeUsernameProblemLanguageResultExecution timeMemory
805482rnl42Prize (CEOI22_prize)C++14
100 / 100
1741 ms301960 KiB
#include <bits/stdc++.h> using namespace std; string to_string(string s) { return s; } template <typename T> string to_string(T v) { bool first = true; string res = "["; for (const auto &x : v) { if (!first) res += ", "; first = false; res += to_string(x); } res += "]"; return res; } template <typename A, typename B> string to_string(pair<A, B> p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; } void dbg_out() { cout << endl; } template <typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cout << ' ' << to_string(H); dbg_out(T...); } #ifdef DEBUG #define dbg(...) cout << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__) #else #define dbg(...) #endif struct Tree { int root = 0; vector<int> parent; vector<vector<int>> adj; void resize(size_t N) { parent.resize(N); adj.resize(N); } }; struct LCA { vector<int> first; vector<int> tourtree; vector<int> height; int tree_shift = 0; void init(Tree& t) { tree_shift = (1<<__lg(4*(int)t.parent.size()-1+10))+3; first.resize(tree_shift); height.resize(tree_shift); tourtree.assign(2*tree_shift, tree_shift-1); height[tree_shift-1] = 1e9; int tour_i = 0; function<void(int)> dfs = [&](const int u) { first[u] = tour_i; //dbg(u, tour_i); tourtree[tree_shift+tour_i++] = u; for (int v : t.adj[u]) { height[v] = height[u]+1; dfs(v); tourtree[tree_shift+tour_i++] = u; } }; dfs(t.root); for (int i = tree_shift-1; i > 0; i--) { tourtree[i] = min(make_pair(height[tourtree[2*i]], tourtree[2*i]), make_pair(height[tourtree[2*i+1]], tourtree[2*i+1])).second; } } int lca(int l, int r) { if (first[l] > first[r]) swap(l, r); /*cerr << "\n-----------\n"; for (int i = 0; i < tree_shift; i++) { cerr << tourtree[tree_shift+i] << " "; } cerr << "\n\n-----------\n" << endl; dbg(tree_shift);*/ l = first[l]+tree_shift, r = first[r]+tree_shift+1; //cerr << "lr " << l << " " << r << endl; pair<int,int> ret(1e9, 1e9); for (; l < r; l >>= 1, r >>= 1) { if (l&1) { ret = min(ret, make_pair(height[tourtree[l]], tourtree[l])); //dbg(tourtree[l], height[tourtree[l]]); l++; } if (r&1) { --r; ret = min(ret, make_pair(height[tourtree[r]], tourtree[r])); } } return ret.second; } }; istream& operator>>(istream& in, Tree& tree) { for (size_t i = 0; i < tree.parent.size(); i++) { in >> tree.parent[i], tree.parent[i]--; if (tree.parent[i] == -2) { tree.parent[i] = -1; tree.root = i; } else { tree.adj[tree.parent[i]].push_back(i); } } return in; } int N, K, Q, T; Tree trees[2]; vector<int> chosen_set; LCA lca[2]; namespace com { void choose_set(vector<int>& v) { for (int i = 0; i < K; i++) { cout << v[i]+1 << (i == K-1 ? '\n' : ' '); } cout << flush; } void query(int u, int v) { cout << "? " << u+1 << " " << v+1 << '\n'; Q++; } pair<vector<array<int,4>>,vector<pair<int,int>>> read_response() { cout << "!\n" << flush; vector<array<int,4>> resp(Q); vector<pair<int,int>> queries(T); for (int i = 0; i < Q; i++) for (int j = 0; j < 4; j++) cin >> resp[i][j]; for (int i = 0; i < T; i++) cin >> queries[i].first >> queries[i].second, queries[i].first--, queries[i].second--; return make_pair(resp, queries); } void answer(int d1, int d2) { cout << d1 << " " << d2 << '\n'; } } int main() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); cin >> N >> K >> Q >> T; Q = 0; for (int i = 0; i < 2; i++) { trees[i].resize(N); cin >> trees[i]; } function<void(int)> dfs = [&](const int u) { if ((int)chosen_set.size() < K) chosen_set.push_back(u); for (int v : trees[0].adj[u]) dfs(v); }; dfs(trees[0].root); sort(chosen_set.begin(), chosen_set.end()); com::choose_set(chosen_set); lca[1].init(trees[1]); lca[0].init(trees[0]); sort(chosen_set.begin(), chosen_set.end(), [](const int a, const int b) { return lca[1].first[a] < lca[1].first[b]; }); vector<int> elems; vector<int> poselem(N, -1); vector<int> cumulsum = {0}; for (int i = 0; i < K-1; i++) { elems.push_back(chosen_set[i]); poselem[elems.back()] = elems.size()-1; //dbg(i, elems.back()); //dbg(chosen_set[i], chosen_set[i+1], lca[1].lca(chosen_set[i], chosen_set[i+1])); elems.push_back(lca[1].lca(chosen_set[i], chosen_set[i+1])); poselem[elems.back()] = elems.size()-1; //dbg(i, elems.back()); com::query(chosen_set[i], chosen_set[i+1]); } elems.push_back(chosen_set.back()); poselem[elems.back()] = elems.size()-1; /*cout << "\n\n\n"; dbg(chosen_set); dbg(elems); cout << "\n\n\n";*/ //vector<pair<int,int>> infotree0(N); //for (int i = 0; i < N; i++) infotree0[i] = make_pair(i, 0); //vector<int> sumuntilroot(N); //vector<int> w_edge(N); auto [resp, queries] = com::read_response(); vector<vector<pair<int,int>>> newadj(N); vector<int> sumuntilroot(N, -1); for (int i = 0; i < Q; i++) { cumulsum.push_back(cumulsum.back()+resp[i][2]); cumulsum.push_back(cumulsum.back()-resp[i][3]); int a = lca[0].lca(elems[2*i], elems[2*i+2]); //cerr << "pair " << a << " " << elems[2*i] << " " << resp[i][0] << endl; newadj[a].emplace_back(elems[2*i], resp[i][0]); newadj[elems[2*i]].emplace_back(a, -resp[i][0]); newadj[a].emplace_back(elems[2*i+2], resp[i][1]); newadj[elems[2*i+2]].emplace_back(a, -resp[i][1]); } // à vérifier function<void(int)> dfs2 = [&](const int u) { for (auto [v, sumw] : newadj[u]) { if (sumuntilroot[v] == -1) { sumuntilroot[v] = sumuntilroot[u]+sumw; dfs2(v); } } }; sumuntilroot[trees[0].root] = 0; dfs2(trees[0].root); /*for (int u = 0; u < N; u++) { if (newadj[u].size()) cerr << "sumuntil " << u << " = " << newadj[u][0].first << ":" << newadj[u][0].second << endl; }*/ for (int i = 0; i < T; i++) { auto& q = queries[i]; int d1 = -2*sumuntilroot[lca[0].lca(q.first, q.second)]+sumuntilroot[q.first]+sumuntilroot[q.second]; //dbg(q.first, q.second); //dbg(poselem[q.first], poselem[q.second]); int d2 = 2*cumulsum[poselem[lca[1].lca(q.first, q.second)]]-cumulsum[poselem[q.first]]-cumulsum[poselem[q.second]]; com::answer(d1, d2); } }

Compilation message (stderr)

Main.cpp: In function 'int main()':
Main.cpp:190:10: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  190 |     auto [resp, queries] = com::read_response();
      |          ^
Main.cpp: In lambda function:
Main.cpp:206:19: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  206 |         for (auto [v, sumw] : newadj[u]) {
      |                   ^
#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...