Advertisement
Guest User

Untitled

a guest
Sep 30th, 2016
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.66 KB | None | 0 0
  1. #include<iostream>
  2. #include<vector>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<cassert>
  6. #include<algorithm>
  7.  
  8. using namespace std;
  9. typedef long long ll;
  10.  
  11. template<class T>
  12. struct splnode {
  13.     typedef splnode<T> node_t;
  14.     typedef pair<T, pair<int, int>> edge;
  15.      
  16.     int idx;
  17.     edge e;
  18.     pair<T, int> dp;
  19.  
  20.     node_t* P;
  21.     node_t* C[2];
  22.  
  23.     int flip;
  24.     node_t* pp;
  25.  
  26.     splnode(int id) : idx(id), P(NULL), flip(0), pp(NULL), e(), dp(){
  27.         C[0] = C[1] = NULL;
  28.         fix();
  29.     }
  30.  
  31.     splnode(int id, int u, int v, ll c) : idx(id), P(NULL), flip(0), pp(NULL), e({ c, { u, v } }), dp(){
  32.         C[0] = C[1] = NULL;
  33.         fix();
  34.     }
  35.  
  36.     splnode(const splnode& other){
  37.         idx = other.idx;
  38.         e = other.e;
  39.         dp = other.dp;
  40.         P = other.P;
  41.         for (int i = 0; i < 2; i++) C[i] = other.C[i];
  42.         flip = other.flip;
  43.         pp = other.pp;
  44.     }
  45.  
  46.     /* Fix the parent pointers of our children.  Additionally if we have any
  47.     * extra data we're tracking (e.g. sum of subtree elements) now is the time to
  48.     * update them (all of the children will already be up to date). */
  49.     void fix() {
  50.         dp = { e.first, idx };
  51.         for (int i = 0; i < 2; i++){
  52.             if (C[i]){
  53.                 C[i]->P = this;
  54.                 dp = max(dp, C[i]->dp);
  55.             }
  56.         }
  57.     }
  58.  
  59.     /* Push the flip bit down the tree. */
  60.     void push_flip() {
  61.         if (!flip) return;
  62.         flip = 0;
  63.         swap(C[0], C[1]);
  64.         if (C[0]) C[0]->flip ^= 1;
  65.         if (C[1]) C[1]->flip ^= 1;
  66.     }
  67.  
  68.     /* Return the direction of this relative its parent. */
  69.     int up() {
  70.         return !P ? -1 : (P->C[0] == this ? 0 : 1);
  71.     }
  72.  
  73.     /* Simple zig step in the 'c' direction when we've reached the root. */
  74.     void zig(int c) {
  75.         node_t* X = C[c];
  76.         if (X->P = P) P->C[up()] = X;
  77.         C[c] = X->C[1 - c];
  78.         X->C[1 - c] = this;
  79.         fix(); X->fix();
  80.         if (P) P->fix();
  81.         swap(pp, X->pp);
  82.     }
  83.  
  84.     /* Zig zig in the 'c' direction both times. */
  85.     void zigzig(int c) {
  86.         node_t* X = C[c];
  87.         node_t* Y = X->C[c];
  88.         if (Y->P = P) P->C[up()] = Y;
  89.         C[c] = X->C[1 - c];
  90.         X->C[c] = Y->C[1 - c];
  91.         Y->C[1 - c] = X;
  92.         X->C[1 - c] = this;
  93.         fix(); X->fix(); Y->fix();
  94.         if (P) P->fix();
  95.         swap(pp, Y->pp);
  96.     }
  97.  
  98.     /* Zig zag first in the 'c' direction then in the '1-c' direciton. */
  99.     void zigzag(int c) {
  100.         node_t* X = C[c];
  101.         node_t* Y = X->C[1 - c];
  102.         if (Y->P = P) P->C[up()] = Y;
  103.         C[c] = Y->C[1 - c];
  104.         X->C[1 - c] = Y->C[c];
  105.         Y->C[1 - c] = this;
  106.         Y->C[c] = X;
  107.         fix(); X->fix(); Y->fix();
  108.         if (P) P->fix();
  109.         swap(pp, Y->pp);
  110.     }
  111.  
  112.     /* Splay this up to the root.  Always finishes without flip set. */
  113.     node_t* splay() {
  114.         for (push_flip(); P;) {
  115.             /* Reorganize flip bits so we can rotate as normal. */
  116.             if (P->P) P->P->push_flip();
  117.             P->push_flip();
  118.             push_flip();
  119.  
  120.             int c1 = up();
  121.             int c2 = P->up();
  122.             if (c2 == -1) {
  123.                 P->zig(c1);
  124.             }
  125.             else if (c1 == c2) {
  126.                 P->P->zigzig(c1);
  127.             }
  128.             else {
  129.                 P->P->zigzag(c2);
  130.             }
  131.         }
  132.         return this;
  133.     }
  134.  
  135.     /* Return the max element of the subtree rooted at this. */
  136.     node_t* last() {
  137.         push_flip();
  138.         return C[1] ? C[1]->last() : splay();
  139.     }
  140.  
  141.     /* Return the min element of the subtree rooted at this. */
  142.     node_t* first() {
  143.         push_flip();
  144.         return C[0] ? C[0]->first() : splay();
  145.     }
  146. };
  147.  
  148. template<class T>
  149. struct linkcut {
  150.     typedef splnode<T> node_t;
  151.     typedef pair<T, pair<int, int>> edge;
  152.  
  153.     linkcut(int n){
  154.         for (int i = 0; i < n; i++) node.emplace_back(i);
  155.     }
  156.  
  157.     void link(int u, int v) {
  158.         make_root(v);
  159.         node[v].pp = &node[u];
  160.     }
  161.  
  162.     void cut(int u, int v) {
  163.         make_root(u);
  164.         node[v].splay();
  165.         if (node[v].pp) {
  166.             node[v].pp = NULL;
  167.         }
  168.         else {
  169.             node[v].C[0]->P = NULL;
  170.             node[v].C[0] = NULL;
  171.             node[v].fix();
  172.         }
  173.     }
  174.  
  175.     /* Move u to root of represented tree. */
  176.     void make_root(int u) {
  177.         access(u);
  178.         node[u].splay();
  179.         if (node[u].C[0]) {
  180.             node[u].C[0]->P = NULL;
  181.             node[u].C[0]->flip ^= 1;
  182.             node[u].C[0]->pp = &node[u];
  183.  
  184.             node[u].C[0] = NULL;
  185.             node[u].fix();
  186.         }
  187.     }
  188.  
  189.     /* Move u to root aux tree.  Return the root of the root aux tree. */
  190.     node_t* access(int u) {
  191.         node_t* x, *pp;
  192.         for (x = node[u].splay(); x->pp; x = pp) {
  193.             pp = x->pp->splay();
  194.             x->pp = NULL;
  195.             if (pp->C[1]) {
  196.                 pp->C[1]->P = NULL;
  197.                 pp->C[1]->pp = pp;
  198.             }
  199.             pp->C[1] = x;
  200.             pp->fix();
  201.         }
  202.         return x;
  203.     }
  204.  
  205.     vector<node_t> node;
  206.  
  207.     void add_edge(int idx){
  208.         pair<int, int> p = node[idx].e.second;
  209.         link(p.first, idx); link(idx, p.second);
  210.     }
  211.  
  212.     void cut_edge(int idx){
  213.         pair<int, int> p = node[idx].e.second;
  214.         cut(p.first, idx); cut(idx, p.second);
  215.     }
  216.  
  217.     ll query(int idx){
  218.         edge e = node[idx].e;
  219.         int u = e.second.first, v = e.second.second;
  220.         ll c = e.first;
  221.         if (u == v) return 0;
  222.  
  223.         make_root(u);
  224.         access(v);
  225.         node[v].splay();
  226.  
  227.         pair<T, int> dp = node[v].C[0]->dp;
  228.         if (dp.first > c){
  229.             cut_edge(dp.second);
  230.             add_edge(idx);
  231.             return c - dp.first;
  232.         }
  233.         return 0;
  234.     }
  235. };
  236.  
  237. int main(){
  238.     int T; scanf("%d", &T);
  239.     while (T--){
  240.         int n, m; scanf("%d%d", &n, &m);
  241.         linkcut<ll> lc(n);
  242.  
  243.         ll here = 0;
  244.         for (int i = 1; i <= n - 1; i++){
  245.             int u; ll c;
  246.             scanf("%d%lld", &u, &c);
  247.             lc.node.emplace_back(lc.node.size(), i, u, c);
  248.             here += c;
  249.         }
  250.  
  251.         for (int i = 0; i < m; i++){
  252.             int u, v; ll c;
  253.             scanf("%d%d%lld", &u, &v, &c);
  254.             lc.node.emplace_back(lc.node.size(), u, v, c);
  255.         }
  256.  
  257.         for (int i = n; i <= 2 * n - 2; i++)
  258.             lc.add_edge(i);
  259.  
  260.         ll ans = 0;
  261.         for (int i = 0; i < m; i++){
  262.             int idx = 2 * n - 1 + i;
  263.             here += lc.query(idx);
  264.             ans ^= here;
  265.         }
  266.  
  267.         printf("%lld\n", ans);
  268.     }
  269. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement