zoukankan      html  css  js  c++  java
  • HDU 4010.Query on The Trees 解题报告

    题意:

      给出一颗树,有4种操作:

         1、如果x和y不在同一棵树上则在xy连边

         2、如果x和y在同一棵树上并且x!=y则把x换为树根并把y和y的父亲分离

         3、如果x和y在同一棵树上则x到y的路径上所有的点权值+w

         4、如果x和y在同一棵树上则输出x到y路径上的最大值

    动态树入门题:

    #include <iostream>
    #include <cstdio>
    using namespace std;
    
    const int MAXN = 333333;
    
    struct node {
        int val, max, inc;
        bool rev;
        node *par, *Ch[2];
    } dt[MAXN], *NIL = dt;
    
    struct LinkcutTree {
        inline void _inc (node * x,  int inc) {
            if (x == NIL) return;
            x->inc += inc, x->val += inc, x->max += inc;
        }
        inline void clear (node *const x) {
            if (x == NIL) return ;
            if (x->inc) {
                _inc (x->Ch[0], x->inc);
                _inc (x->Ch[1], x->inc);
                x->inc = 0;
            }
            if (x->rev) {
                swap (x->Ch[0], x->Ch[1]);
                x->Ch[0]->rev ^= 1;
                x->Ch[1]->rev ^= 1;
                x->rev = 0;
            }
        }
        inline void update (node * x) {
            clear (x);
            clear (x->Ch[0]), clear (x->Ch[1]);
            x->max = max (x->val, max (x->Ch[0]->max, x->Ch[1]->max) );
        }
        void Rotate (node *x) {
            node *p = x->par, *g = p->par;
            clear (p),clear (x);
            int c = p->Ch[0] == x; //0左旋,1右旋
            p->Ch[c ^ 1] = x->Ch[c];
            if (x->Ch[c] != NIL) x->Ch[c]->par = p;
            x->par = g;
            if (g->Ch[0] == p) g->Ch[0] = x; else
                  if (g->Ch[1] == p) g->Ch[1] = x;
            x->Ch[c] = p;
            p->par = x;
            update (p);
        }
        void Splay (node *x) {
               if(x==NIL) return ;
            while (x->par != NIL && (x->par->Ch[0] == x || x->par->Ch[1] == x) ) {
                if (x->par != NIL)
                    Rotate (x);
                else {
                    node *p = x->par, *g = p->par;
                    if ( (g->Ch[1] == p) == (p->Ch[1] == x) )
                        Rotate (p), Rotate (x);
                    else
                        Rotate (x), Rotate (x);
                }
            }
            update (x);
        }
        node *Access (node *u) {
            node *v = NIL;
            for (; u != NIL; u = u->par) {
                Splay (u);
                u->Ch[1] = v;
                update (v = u);
            }
            return v;
        }
        node *getroot (node *x) {
            for (x = Access (x); clear (x), x->Ch[0] != NIL; x = x->Ch[0]);
            return x;
        }
        inline void evert (node *x) {
            Access (x)->rev ^= 1;
            Splay (x);
        }
        inline void link (node *x, node *y) {
            evert (x);
            x->par = y;
            Access (x);
        }
        inline void cut (node *x, node *y) {
            evert (x);
            Access (y);
            Splay (y);
            y->Ch[0]->par = NIL;
            y->Ch[0] = NIL;
            update (y);
        }
        inline int query (node *x, node *y) {
            evert (x);
            Access (y), Splay (y);
            return y->max;
        }
        inline void modify (node *x, node *y, int w) {
            evert (x);
            Access (y), Splay (y);
            _inc (y, w);
        }
    } LCT;
    int n, m;
    int main() {
        while (scanf ("%d", &n) != EOF) {
            for (int i = 0; i <= n; i++) {
                dt[i].val = dt[i].max = dt[i].inc = 0;
                dt[i].par = dt[i].Ch[0] = dt[i].Ch[1] = NIL;
                dt[i].rev = 0;
            }
            for (int i = 1, x, y; i < n; ++i) {
                scanf ("%d %d", &x, &y);
                LCT.link (dt + x, dt + y);
            }
            for (int i = 1, x; i <= n; ++i) {
                scanf ("%d", &x);
                node *tem = dt + i;
                LCT.Splay (tem);
                tem->val = tem->max = x;
                LCT.update (tem);
            }
            scanf ("%d", &m);
            for (int i = 0, op, x, y, z; i < m; ++i) {
                scanf ("%d%d%d", &op, &x, &y);
                switch (op) {
                case 1:
                    if (LCT.getroot (dt + x) == LCT.getroot (dt + y) ) printf ("-1
    ");
                    else LCT.link (dt + x, dt + y); break;
                case 2:
                    if (x == y || LCT.getroot (dt + x) != LCT.getroot (dt + y) ) printf ("-1
    ");
                    else LCT.cut (dt + x, dt + y); break;
                case 3:
                    scanf ("%d", &z);
                    if (LCT.getroot (dt + y) != LCT.getroot (dt + z) ) printf ("-1
    ");
                    else LCT.modify (dt + y, dt + z, x); break;
                case 4:
                    if (LCT.getroot (dt + x) != LCT.getroot (dt + y) ) printf ("-1
    ");
                    else printf ("%d
    ", LCT.query (dt + x, dt + y) ); break;
                }
            }
            putchar (10);
        }
    }
    View Code
  • 相关阅读:
    Codeforces 834D The Bakery
    hdu 1394 Minimum Inversion Number
    Codeforces 837E Vasya's Function
    Codeforces 837D Round Subset
    Codeforces 825E Minimal Labels
    Codeforces 437D The Child and Zoo
    Codeforces 822D My pretty girl Noora
    Codeforces 799D Field expansion
    Codeforces 438D The Child and Sequence
    Codeforces Round #427 (Div. 2) Problem D Palindromic characteristics (Codeforces 835D)
  • 原文地址:https://www.cnblogs.com/keam37/p/4006257.html
Copyright © 2011-2022 走看看