AhmedAshraff

Untitled

Nov 24th, 2024
39
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.72 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define boAshraf ios_base::sync_with_stdio(false); cin.tie(NULL);
  3. #define ll long long
  4. #define sz(s) (int)(s).size()
  5. #define all(s) (s).begin(),(s).end()
  6. using namespace std;
  7. void File();
  8. void sol();
  9. struct Node {
  10.     int val = 0;
  11. } neutral;
  12.  
  13. struct segtree {
  14.     segtree *left = nullptr, *right = nullptr;
  15.     Node node = {};
  16.     int start, end;
  17.  
  18.     segtree(int l = 0, int r = 0) : start(l), end(r) {}
  19.  
  20.     void extend() {
  21.         if (left == nullptr) {
  22.             int mid = (start + end) >> 1;
  23.             left = new segtree(start, mid);
  24.             right = new segtree(mid + 1, end);
  25.         }
  26.     }
  27.     Node pushup(Node a, Node b) {
  28.         Node ret;
  29.         ret.val = max(a.val,b.val);
  30.         return ret;
  31.     }
  32.     void build(vector<int>& v) {
  33.         if (start == end) {
  34.             node.val = v[start];
  35.             return;
  36.         }
  37.         extend();
  38.         left->build(v);
  39.         right->build(v);
  40.         node = pushup(left->node, right->node);
  41.     }
  42.     void update(int l, int r, int val) {
  43.         if (start > r || end < l) return;
  44.         if (start >= l && end <= r) {
  45.             node.val = val;
  46.             return;
  47.         }
  48.         extend();
  49.         left->update(l, r, val);
  50.         right->update(l, r, val);
  51.         node = pushup(left->node, right->node);
  52.     }
  53.     Node query(int l, int r) {
  54.         if (r < start || end < l) return neutral;
  55.         if (l <= start && end <= r) return node;
  56.         extend();
  57.         Node ret = pushup(left->query(l, r), right->query(l, r));
  58.         return ret;
  59.     }
  60.     ~segtree() {
  61.         if (left == nullptr) return;
  62.         delete left;
  63.         delete right;
  64.     }
  65. };
  66. class heavy_light_decomposition {
  67.     int n, is_value_in_edge;
  68.     vector<int> parent, depth, heavy, root, pos_in_array, pos_to_node, size;
  69.     segtree *seg;
  70.     struct TREE {
  71.         int cnt_edges = 1;
  72.         vector<vector<int>> adj;
  73.         //need for value in edges
  74.         vector<vector<int>> edge_idx;
  75.         //edge_to need for undirected tree //end of edge in directed tree
  76.         vector<int> edge_to, edge_cost;
  77.         TREE(int n) : adj(n + 1), edge_idx(n + 1), edge_to(n + 1), edge_cost(n + 1) {
  78.         }
  79.         void add_edge(int u, int v, ll c) {
  80.             adj[u].push_back(v);
  81.             adj[v].push_back(u);
  82.             edge_idx[u].push_back(cnt_edges);
  83.             edge_idx[v].push_back(cnt_edges);
  84.             edge_cost[cnt_edges] = c;
  85.             cnt_edges++;
  86.         }
  87.     } tree;
  88.     int dfs_hld(int node) {
  89.         int size = 1, max_sub_tree = 0;
  90.         for (int i = 0; i < (int) tree.adj[node].size(); i++) {
  91.             int ch = tree.adj[node][i], edge_idx = tree.edge_idx[node][i];
  92.             if (ch != parent[node]) {
  93.                 tree.edge_to[edge_idx] = ch;
  94.                 parent[ch] = node;
  95.                 depth[ch] = depth[node] + 1;
  96.                 int child_size = dfs_hld(ch);
  97.                 if (child_size > max_sub_tree)
  98.                     heavy[node] = ch, max_sub_tree = child_size;
  99.                 size += child_size;
  100.             }
  101.         }
  102.         return size;
  103.     }
  104.  
  105.     vector<tuple<int, int, bool>> get_path(int u, int v) { //l,r,must_reverse?
  106.         vector<pair<int, int>> tmp[2];
  107.         bool idx = 1;
  108.         while (root[u] != root[v]) {
  109.             if (depth[root[u]] > depth[root[v]]) {
  110.                 swap(u, v);
  111.                 idx = !idx;
  112.             }
  113.             //if value in edges ,you need value of root[v] also (connecter edge)
  114.             tmp[idx].push_back( { pos_in_array[root[v]], pos_in_array[v] });
  115.             v = parent[root[v]];
  116.         }
  117.         if (depth[u] > depth[v]) {
  118.             swap(u, v);
  119.             idx = !idx;
  120.         }
  121.         if (!is_value_in_edge || u != v)
  122.             tmp[idx].push_back( { pos_in_array[u] + is_value_in_edge, pos_in_array[v] });
  123.         reverse(all(tmp[1]));
  124.         vector<tuple<int, int, bool>> rt;
  125.  
  126.         for (int i = 0; i < 2; i++)
  127.             for (auto &it : tmp[i])
  128.                 rt.emplace_back(it.first, it.second, i == 0);
  129.         return rt; //u is LCA
  130.     }
  131. public:
  132.     heavy_light_decomposition(int n, bool is_value_in_edge) :
  133.             n(n), is_value_in_edge(is_value_in_edge), tree(n + 1) {
  134.         heavy = vector<int>(n + 1, -1);
  135.         seg=new segtree(1,n);
  136.         parent = depth = root = pos_in_array = pos_to_node = size = vector<int>(n + 1);
  137.     }
  138.     void add_edge(int u, int v, int c = 0) {
  139.         tree.add_edge(u, v, c);
  140.     }
  141.     void build_chains(int src = 1) {
  142.         parent[src] = -1;
  143.         dfs_hld(src);
  144.         for (int chain_root = 1, pos = 1; chain_root <= n; chain_root++) {
  145.             if (parent[chain_root] == -1 || heavy[parent[chain_root]] != chain_root)
  146.                 for (int j = chain_root; j != -1; j = heavy[j]) {
  147.                     root[j] = chain_root;
  148.                     pos_in_array[j] = pos++;
  149.                     pos_to_node[pos_in_array[j]] = j;
  150.                 }
  151.         }
  152.         if (is_value_in_edge)
  153.             for (int i = 1; i < n; i++)
  154.                 update_edge(i, tree.edge_cost[i]);
  155.     }
  156.     void update_node(int node, int value) {
  157.         seg->update(pos_in_array[node],pos_in_array[node], value);
  158.     }
  159.     void update_edge(int edge_idx, int value) {
  160.         update_node(tree.edge_to[edge_idx], value);
  161.     }
  162.     void update_path(int u, int v, ll c) {
  163.         vector<tuple<int, int, bool>> intervals = get_path(u, v);
  164.         for (auto &it : intervals)
  165.             seg->update(get<0>(it), get<1>(it), c);
  166.     }
  167.  
  168.     Node query_in_path(int u, int v) {
  169.         vector<tuple<int, int, bool>> intervals = get_path(u, v);
  170.         //initial value,check if handling u == v
  171.         Node query_res = neutral;
  172.         for (auto &it : intervals) {
  173.             int l, r;
  174.             bool rev;
  175.             tie(l, r, rev) = it;
  176.             Node cur = seg->query(l, r);
  177.             query_res = seg->pushup(query_res,cur);
  178.         }
  179.         return query_res;
  180.     }
  181. };
  182.  
  183. int main() {
  184.     boAshraf
  185.     File();
  186.     int t = 1;
  187.     cin >> t;
  188.     while (t--) {
  189.         sol();
  190.     }
  191.     return 0;
  192. }
  193.  
  194. void sol() {
  195.     int n;cin>>n;
  196.     heavy_light_decomposition hld(n,true);
  197.     for (int i = 0; i < n - 1; ++i) {
  198.         int u,v, c;
  199.         cin>>u>>v>>c;
  200.         hld.add_edge(u,v,c);
  201.     }
  202.     hld.build_chains();
  203.     string s;
  204.     while(cin>>s && s!="DONE"){
  205.         if(s[0]=='C'){
  206.             int idx,v;
  207.             cin>>idx>>v;
  208.             hld.update_edge(idx,v);
  209.         }
  210.         else{
  211.             int u,v;cin>>u>>v;
  212.             auto ans=hld.query_in_path(u,v);
  213.             cout<<ans.val<<'\n';
  214.         }
  215.     }
  216. }
  217.  
  218. void File() {
  219. #ifndef ONLINE_JUDGE
  220.     freopen("input.txt", "r", stdin);
  221.     freopen("output.txt", "w", stdout);
  222. #endif
  223. }
  224.  
Advertisement
Add Comment
Please, Sign In to add comment