Submission #789224

#TimeUsernameProblemLanguageResultExecution timeMemory
789224ymmPrize (CEOI22_prize)C++17
100 / 100
2519 ms561004 KiB
#include <bits/stdc++.h> #define Loop(x,l,r) for (ll x = (l); x < (r); ++x) #define LoopR(x,l,r) for (ll x = (r)-1; x >= (l); --x) typedef long long ll; typedef std::pair<int,int> pii; using namespace std; struct tree { int n; int rt; vector<vector<int>> A; vector<int> pos, ord; static int constexpr lg = 22; vector<int> rmq[lg]; void dfs(int v, int &t) { pos[v] = ord.size(); ord.push_back(v); for (int u : A[v]) { dfs(u, t); ord.push_back(v); } } int mn(int v, int u) const { return pos[v] < pos[u]? v: u; } void rmqmake() { rmq[0] = ord; int n = ord.size(); Loop (i,0,lg-1) { rmq[i+1].resize(ord.size()); for (int j = 0; j+(2<<i) <= n; ++j) rmq[i+1][j] = mn(rmq[i][j], rmq[i][j+(1<<i)]); } } int lca(int v, int u) const { v = pos[v]; u = pos[u]; if (v > u) swap(v, u); int len = u-v+1; int k = __lg(len); return mn(rmq[k][v], rmq[k][u+1-(1<<k)]); } void init0(int sz) { n = sz; A.clear(); A.resize(n); } void init1() { pos.resize(n); ord.clear(); int dard = 0; dfs(rt, dard); rmqmake(); } }; void read_tree(tree &t) { Loop (i,0,t.n) { int p; scanf("%d", &p); --p; if (p < 0) t.rt = i; else t.A[p].push_back(i); } t.init1(); } void dfs_ord(const tree &t, vector<int> &vec, int v) { vec.push_back(v); for (int u : t.A[v]) dfs_ord(t, vec, u); } vector<int> dis_from_root(const tree &t, const vector<int> &ord, const vector<pii> &res) { vector<int> ans(t.n); int dis = 0; Loop (i,0,ord.size()-1) { dis -= res[i].first; ans[t.lca(ord[i], ord[i+1])] = dis; dis += res[i].second; ans[ord[i+1]] = dis; } //Loop (i,p,ord.size()-1) { // dis -= res[i].first; // ans[t.lca(ord[i], ord[i+1])] = dis; // dis += res[i].second; // ans[ord[i+1]] = dis; //} //dis = 0; //LoopR (i,0,p) { // dis -= res[i].second; // ans[t.lca(ord[i], ord[i+1])] = dis; // dis += res[i].first; // ans[ord[i]] = dis; //} return ans; } int get_dis(const tree &t, const vector<int> &dis, int v, int u) { int l = t.lca(v, u); return -2*dis[l] + dis[v] + dis[u]; } int main() { tree T1, T2; int n, k, q, t; scanf("%d%d%d%d", &n, &k, &q, &t); T1.init0(n); T2.init0(n); read_tree(T1); read_tree(T2); vector<int> tmp; dfs_ord(T1, tmp, T1.rt); tmp.resize(k); set<int> myset(tmp.begin(), tmp.end()); tmp.clear(); dfs_ord(T2, tmp, T2.rt); vector<int> ord; for (int x : tmp) { if (myset.count(x)) ord.push_back(x); } for (int x : myset) printf("%d ", x+1); printf("\n"); Loop (i,0,k-1) printf("? %d %d\n", ord[i]+1, ord[i+1]+1); printf("!\n"); fflush(stdout); vector<pii> res1, res2; Loop (i,0,k-1) { int a, b, c, d; scanf("%d%d%d%d", &a, &b, &c, &d); res1.push_back({a, b}); res2.push_back({c, d}); } vector<int> dis1, dis2; dis1 = dis_from_root(T1, ord, res1); dis2 = dis_from_root(T2, ord, res2); vector<pii> ans; while (t--) { int v, u; scanf("%d%d", &v, &u); --v; --u; int x = get_dis(T1, dis1, v, u); int y = get_dis(T2, dis2, v, u); ans.push_back({x, y}); } for (auto [x, y] : ans) printf("%d %d\n", x, y); fflush(stdout); }

Compilation message (stderr)

Main.cpp: In function 'std::vector<int> dis_from_root(const tree&, const std::vector<int>&, const std::vector<std::pair<int, int> >&)':
Main.cpp:2:40: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
    2 | #define Loop(x,l,r) for (ll x = (l); x < (r); ++x)
      |                                        ^
Main.cpp:86:2: note: in expansion of macro 'Loop'
   86 |  Loop (i,0,ord.size()-1) {
      |  ^~~~
Main.cpp: In function 'void read_tree(tree&)':
Main.cpp:65:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   65 |   scanf("%d", &p);
      |   ~~~~~^~~~~~~~~~
Main.cpp: In function 'int main()':
Main.cpp:118:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  118 |  scanf("%d%d%d%d", &n, &k, &q, &t);
      |  ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:145:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  145 |   scanf("%d%d%d%d", &a, &b, &c, &d);
      |   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:156:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  156 |   scanf("%d%d", &v, &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...