Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <random>
- #include <algorithm>
- #include <unordered_map>
- #include <unordered_set>
- #include <set>
- //#include "Treap.h"
- //#include "ImplicitTreap.cpp"
- //#include "RootedTree.h"
- //#include "Graph.h"
- using namespace std;
- //
- // Created by newuserkk on 5/29/18.
- //
- struct RootedTreeNode {
- int id;
- RootedTreeNode* parent;
- int parent_cost = 0;
- set<RootedTreeNode*> children;
- int color;
- int depth = 1;
- vector<RootedTreeNode*> lca_dp;
- explicit RootedTreeNode(int id);
- void recalc();
- };
- struct RootedTree {
- RootedTreeNode *root;
- vector<RootedTreeNode*> nodes;
- explicit RootedTree(RootedTreeNode *root = nullptr);
- void add(RootedTreeNode *node, RootedTreeNode *child, int cost);
- void connect(RootedTreeNode *node, RootedTreeNode *child, int cost);
- void lca_precalc();
- RootedTreeNode *lca(RootedTreeNode *v, RootedTreeNode *u);
- RootedTreeNode* get_node(int id);
- int get_min_on_path(RootedTreeNode *u, RootedTreeNode *v);
- int size();
- };
- int randint(int min, int max) {
- random_device r;
- default_random_engine e1(r());
- uniform_int_distribution<int64_t> uniform_dist(min, max);
- return (int) uniform_dist(e1);
- }
- //
- // Created by newuserkk on 5/29/18.
- //
- RootedTreeNode::RootedTreeNode(int id) {
- this->id = id;
- // this->children = std::move(children);
- // this->parent = parent;
- recalc();
- }
- void RootedTreeNode::recalc() {
- if (!parent) {
- this->depth = 1;
- } else {
- this->depth = parent->depth + 1;
- }
- }
- RootedTree::RootedTree(RootedTreeNode *root) {
- this->root = root;
- nodes.push_back(root);
- }
- void RootedTree::add(RootedTreeNode *node, RootedTreeNode *child, int cost) {
- nodes.push_back(child);
- connect(node, child, cost);
- node->recalc();
- child->recalc();
- }
- void RootedTree::connect(RootedTreeNode *node, RootedTreeNode *child, int cost) {
- node->children.insert(child);
- child->parent = node;
- child->parent_cost = cost;
- }
- RootedTreeNode *RootedTree::lca(RootedTreeNode *v, RootedTreeNode *u) {
- auto n = (int) floor(log2(nodes.size()));
- RootedTreeNode *first = v;
- RootedTreeNode *second = u;
- if (first->depth > second->depth) {
- swap(first, second);
- }
- // second depth > first depth
- for (auto i = n; i >= 0; --i) {
- if (second->depth - pow(2, i) >= first->depth) {
- second = second->lca_dp[i];
- }
- }
- if (first == second) {
- return first;
- }
- for (auto i = n; i >= 0; --i) {
- if (first->lca_dp[i] != second->lca_dp[i]) {
- first = first->lca_dp[i];
- second = second->lca_dp[i];
- }
- }
- return first->lca_dp[0];
- }
- void RootedTree::lca_precalc() {
- int n = (int)nodes.size();
- int lg = (n != 1 ? (int)ceil(log2(n)) : 1);
- for (auto &node : nodes) {
- for (int i = 0; i < lg; ++i) {
- node->lca_dp.push_back(nullptr);
- }
- node->lca_dp[0] = node->parent ? node->parent : node;
- }
- for (int i = 1; i < lg; ++i) {
- for (auto &node : nodes) {
- node->lca_dp[i] = node->lca_dp[i - 1]->lca_dp[i - 1];
- }
- }
- }
- int RootedTree::get_min_on_path(RootedTreeNode *u, RootedTreeNode *v) {
- if (u == v) {
- return 0;
- }
- RootedTreeNode* lca_node = lca(u, v);
- int res = INT32_MAX;
- if (lca_node != u) {
- res = u->parent_cost;
- RootedTreeNode *u_parent = u->parent;
- while (u_parent != lca_node) {
- res = min(res, u_parent->parent_cost);
- u_parent = u_parent->parent;
- }
- }
- if (lca_node != v) {
- res = min(res, v->parent_cost);
- RootedTreeNode *v_parent = (v != lca_node ? v->parent : v);
- while (v_parent != lca_node) {
- res = min(res, v_parent->parent_cost);
- v_parent = v_parent->parent;
- }
- }
- return res;
- }
- RootedTreeNode *RootedTree::get_node(int id) {
- return nodes[id];
- }
- int RootedTree::size() {
- return (int)nodes.size();
- }
- void mainA() {
- int n;
- cin >> n;
- auto tree = new RootedTree(new RootedTreeNode(0));
- int x;
- for (int i = 0; i < n - 1; ++i) {
- cin >> x;
- tree->add(tree->get_node(x - 1), new RootedTreeNode(tree->size()), 0);
- }
- tree->lca_precalc();
- int m, u, v;
- cin >> m;
- for (int i = 0; i < m; ++i) {
- cin >> u >> v;
- RootedTreeNode* lca = tree->lca(tree->get_node(u - 1), tree->get_node(v - 1));
- cout << lca->id + 1 << "\n";
- }
- }
- void mainB() {
- int n;
- cin >> n;
- auto tree = new RootedTree(new RootedTreeNode(0));
- int p, cost;
- for (int i = 0; i < n - 1; ++i) {
- cin >> p >> cost;
- tree->add(tree->get_node(p - 1), new RootedTreeNode(tree->size()), cost);
- }
- tree->lca_precalc();
- int m, u, v;
- cin >> m;
- for (int i = 0; i < m; ++i) {
- cin >> u >> v;
- cout << tree->get_min_on_path(tree->get_node(u - 1),
- tree->get_node(v - 1)) << "\n";
- }
- }
- //void mainH() {
- // int n;
- // cin >> n;
- //
- // auto tree = new RootedTree(new RootedTreeNode(0));
- //
- // for (int i = 1; i < n; ++i) {
- // tree->nodes.push_back(new RootedTreeNode(i));
- // }
- //
- // int parent, color;
- // for (int i = 0; i < n; ++i) {
- // cin >> parent >> color;
- // if (parent == 0) {
- // tree->root = tree->get_node(i);
- // } else {
- // tree->connect(tree->get_node(parent - 1), tree->get_node(i));
- // }
- // tree->get_node(i)->set_color(color);
- // }
- //
- // tree->dfs(tree->root);
- // for (auto node: tree->nodes) {
- // cout << node->subtree_colors_count << " ";
- // }
- //}
- //void mainI() {
- // int n, m;
- // cin >> n >> m;
- // auto graph = new Graph();
- // for (int i = 0; i < n; ++i) {
- // graph->add_node(new EulerNode(i));
- // }
- //
- // string op;
- // int u, v;
- // for (int j = 0; j < m; ++j) {
- // cin >> op;
- // if (op == "link") {
- // cin >> u >> v;
- // graph->nodes[u]->tree->link(graph->nodes[u], graph->nodes[v]);
- // } else if (op == "cut") {
- // cin >> u >> v;
- // graph->nodes[u]->tree->cut(graph->nodes[u], graph->nodes[v]);
- // } else {
- // cin >> u;
- // cout << graph->nodes[u]->tree->get_size() << "\n";
- // }
- // }
- //}
- int main(int argc, char *argv[]) {
- string arg = (argc > 1 ? argv[1] : "");
- if (arg == "--readfile") {
- freopen("test.in", "r", stdin);
- } else {
- // freopen("minonpath.in", "r", stdin);
- // freopen("minonpath.out", "w", stdout);
- }
- ios_base::sync_with_stdio(false);
- mainA();
- // mainB();
- // mainH();
- // mainI();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement