999ms

Spoj QTREE HLD on edges

Jun 13th, 2019
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const int sz = 10000;
  5. const int lgsz = 15;
  6.  
  7. vector<int> g[sz];
  8.  
  9. struct segment_tree {
  10.   vector<int> t;
  11.   int n;
  12.   segment_tree(int n) {
  13.     this->n = n;
  14.     t.assign(n * 4, 0);
  15.   }
  16.   void upd(int v, int tl, int tr, int i, int val) {
  17.     if(tl + 1 == tr) {
  18.       t[v] = val;
  19.     } else {
  20.       int tm = (tl + tr) / 2;
  21.       if(i < tm) {
  22.         upd(v * 2 + 1, tl, tm, i, val);
  23.       } else {
  24.         upd(v * 2 + 2, tm, tr, i, val);
  25.       }
  26.       t[v] = max(t[v * 2 + 1], t[v * 2 + 2]);
  27.     }
  28.   }
  29.   int get(int v, int tl, int tr, int l, int r) {
  30.     if(tl >= r || tr <= l) return 0;
  31.     if(tl >= l && tr <= r) return t[v];
  32.     int tm = (tl + tr) / 2;
  33.     return max(
  34.       get(v * 2 + 1, tl, tm, l, r),
  35.       get(v * 2 + 2, tm, tr, l, r)
  36.     );
  37.   }
  38. };
  39.  
  40.  
  41. int tsize[sz];
  42. int par[sz][lgsz];
  43. int depth[sz];
  44.  
  45. void dfs(int f, int p, int h = 0) {
  46.   tsize[f] = 1;
  47.   par[f][0] = p;
  48.   depth[f] = h;
  49.   for(int h=1;h<lgsz;h++) {
  50.     par[f][h] = par[par[f][h-1]][h-1];
  51.   }
  52.   for(int v : g[f]) {
  53.     if(v != p) {
  54.       dfs(v, f, h + 1);
  55.       tsize[f] +=  tsize[v];
  56.     }
  57.   }
  58. }
  59.  
  60. void buildHLD(int f, int p, int c, vector<vector<int> > & hld) {
  61.   bool used = false;
  62.   for(int v : g[f]) {
  63.     if(v == p) continue;
  64.     if(tsize[v] > tsize[f] / 2) {
  65.       used = true;
  66.       if(c) {
  67.         hld.back().push_back(v);
  68.         buildHLD(v, f, 1, hld);
  69.       } else {
  70.         hld.push_back({f, v});
  71.         buildHLD(v, f, 1, hld);
  72.       }
  73.       break;
  74.     }
  75.   }
  76.   if(!used) {
  77.     hld.push_back({f});
  78.   }
  79.   for(int v : g[f]) {
  80.     if(v == p) continue;
  81.     if(tsize[v] <= tsize[f] / 2) {
  82.       buildHLD(v, f, 0, hld);
  83.     }
  84.   }
  85. }
  86.  
  87. int inhld[sz];
  88. int ind[sz];
  89.  
  90. int lca(int f, int t) {
  91.   if(depth[f] < depth[t]) swap(f,t);
  92.   for(int i=lgsz-1;i>=0;i--) {
  93.     if(depth[par[f][i]] >= depth[t]) {
  94.       f = par[f][i];
  95.     }
  96.   }
  97.   if(f == t) return f;
  98.   for(int i=lgsz-1;par[f][0] != par[t][0];i--) {
  99.     if(par[f][i] != par[t][i]) {
  100.       f = par[f][i];
  101.       t = par[t][i];
  102.     }
  103.   }
  104.   return par[f][0];
  105. }
  106.  
  107. struct HLD {
  108.   vector<int> head;
  109.   vector<segment_tree> hld;
  110.   int n;
  111.   HLD(vector<vector<int> > & hways) {
  112.     this -> n = hways.size();
  113.     for(int i=0;i<n;i++) {
  114.       hld.emplace_back((int)hways[i].size());
  115.       head.push_back(hways[i][0]);
  116.     }
  117.   }
  118.   void upd(int v, int value) {
  119.     hld[inhld[v]].upd(0, 0, hld[inhld[v]].n, ind[v], value);
  120.   }
  121.   int get(int f, int t) {
  122.     int u = lca(f, t);
  123.     int ans = 0;
  124.     while(inhld[f] != inhld[u]) {
  125.       ans = max(ans, hld[inhld[f]].get(0, 0, hld[inhld[f]].n, 0, ind[f] + 1));
  126.       f = par[head[inhld[f]]][0];
  127.     }
  128.     while(inhld[t] != inhld[u]) {
  129.       ans = max(ans, hld[inhld[t]].get(0, 0, hld[inhld[t]].n, 0, ind[t] + 1));
  130.       t = par[head[inhld[t]]][0];
  131.     }
  132.     if(depth[f] < depth[t]) swap(f, t);
  133.     ans = max(ans, hld[inhld[f]].get(0, 0, hld[inhld[f]].n, ind[t] + 1, ind[f]+ 1));
  134.     return ans;
  135.   }
  136. };
  137.  
  138. void solve() {
  139.   int n;
  140.   cin >> n;
  141.   for(int i=0;i<n;i++) { g[i].clear(); }
  142.   vector<pair<int,int> > edges;
  143.   vector<int> w;
  144.   for(int i=0;i<n - 1;i++) {
  145.     int f, t, curw;
  146.     cin >> f >> t >> curw;
  147.     f--,t--;
  148.     edges.push_back(make_pair(f,t));
  149.     g[f].push_back(t);
  150.     g[t].push_back(f);
  151.     w.push_back(curw);
  152.   }
  153.   dfs(0, 0);
  154.   vector<int> etov(n - 1);
  155.   for(int i=0;i<n-1;i++) {
  156.     int f = edges[i].first;
  157.     int t = edges[i].second;
  158.     if(par[f][0] == t) {
  159.       etov[i] = f;
  160.     } else {
  161.       etov[i] = t;
  162.     }
  163.   }
  164.   vector<vector<int> > hways;
  165.   buildHLD(0, 0, 0, hways);
  166.   for(int i=0;i<hways.size();i++) {
  167.     for(int j=0;j<hways[i].size();j++) {
  168.       inhld[hways[i][j]] = i;
  169.       ind[hways[i][j]] = j;
  170.     }
  171.   }  
  172.   HLD hld (hways);
  173.   for(int i=0;i<n-1;i++) {
  174.     hld.upd(etov[i], w[i]);
  175.   }
  176.   string t;
  177.   cin >> t;
  178.   while(t != "DONE") {
  179.     if(t == "QUERY") {
  180.       int u, v;
  181.       cin >> u >> v;
  182.       u--,v--;
  183.       cout << hld.get(u, v) << "\n";
  184.     } else {
  185.       int i, val;
  186.       cin >> i >> val;
  187.       i--;
  188.       hld.upd(etov[i], val);
  189.     }
  190.     cin >> t;
  191.   }
  192. }
  193.  
  194.  
  195. int main() {
  196.   ios_base::sync_with_stdio(false);
  197.   cin.tie(nullptr);
  198.   int t;
  199.   cin >> t;
  200.   while(t--) {
  201.     solve();
  202.   }
  203.   return 0;
  204. }
Add Comment
Please, Sign In to add comment