• 【BZOJ1036】【LCT版】树的统计Count


    Description

    一 棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身

    Input

    输 入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数 q,表示操作的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。 对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到 30000之间。

    Output

    对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。

    Sample Input

    4
    1 2
    2 3
    4 1
    4 2 1 3
    12
    QMAX 3 4
    QMAX 3 3
    QMAX 3 2
    QMAX 2 3
    QSUM 3 4
    QSUM 2 1
    CHANGE 1 5
    QMAX 3 4
    CHANGE 3 6
    QMAX 3 4
    QMAX 2 4
    QSUM 3 4

    Sample Output

    4
    1
    2
    2
    10
    6
    5
    6
    5
    16

    Hint

    【分析】

    随便写了一个LCT的版本,比树链剖分慢...

    现在发现LCT真是个好东西,好写又有用。

      1 /*
      2 唐代白居易
      3 《白云泉》
      4 天平山上白云泉,云自无心水自闲。
      5 何必奔冲山下去,更添波浪向人间。 
      6 */
      7 #include <iostream>
      8 #include <cstdio>
      9 #include <algorithm>
     10 #include <cstring>
     11 #include <vector>
     12 #include <utility>
     13 #include <iomanip>
     14 #include <string>
     15 #include <cmath>
     16 #include <queue>
     17 #include <assert.h>
     18 #include <map>
     19 #include <ctime>
     20 #include <cstdlib>
     21 #include <stack>
     22 #define LOCAL
     23 const int INF = 0x7fffffff;
     24 const int MAXN = 30000  + 10;
     25 const int maxnode = 1000000;
     26 const int maxm= 30000 * 2 + 10;
     27 using namespace std;
     28 
     29 struct Link_Cut_Tree{
     30        struct Node{
     31               int val, sum, Max;//用来debug 
     32               int delta;
     33               Node *parent;
     34               Node *ch[2];
     35        }node[MAXN], *cur, _null, *null;
     36        Node *tmp[MAXN];
     37        
     38        bool is_root(Node* t){//判断是否是splay的根 
     39             if (t == null || (t->parent->ch[0] != t && t->parent->ch[1] != t)) return 1;
     40             return 0;
     41        }
     42        //本来以为不要pushdown了,结果还是要 
     43        void pushdown(Node *t){
     44             if (t == null) return;
     45             if (t->delta){
     46                t->delta = 0;
     47                if (t->ch[0] != null) t->ch[0]->delta ^= 1;
     48                if (t->ch[1] != null) t->ch[1]->delta ^= 1;
     49                swap(t->ch[0], t->ch[1]); 
     50             } 
     51        }
     52        //更新 
     53        void update(Node *t){
     54             if (t == null) return;
     55             t->sum = t->val;
     56             if (t->ch[0] != null) t->sum += t->ch[0]->sum;
     57             if (t->ch[1] != null) t->sum += t->ch[1]->sum;
     58             t->Max = max(t->val, max(t->ch[0]->Max, t->ch[1]->Max));
     59             return;
     60        }
     61        void init(){
     62             null = &_null;
     63             _null.val = _null.sum = _null.Max = -INF;
     64             _null.delta = 0;
     65             _null.parent = _null.ch[0] = _null.ch[1] = null;
     66             
     67             cur = node + 1;
     68        }
     69        Node* NEW(int val){
     70             cur->parent = cur->ch[0] = cur->ch[1] = null;
     71             cur->val = cur->Max = cur->sum = val;
     72             cur->delta = 0;
     73             return cur++;
     74        } 
     75        void rotate(Node *t, int d){
     76             if (is_root(t)) return;
     77             Node *p = t->parent;
     78             p->ch[d ^ 1] = t->ch[d];
     79             if (t->ch[d] != null) t->ch[d]->parent = p;
     80             t->parent = p->parent;
     81             if (p != null){
     82                if (p->parent->ch[0] == p) p->parent->ch[0] = t;
     83                else if (p->parent->ch[1] == p) p->parent->ch[1] = t;
     84             }
     85             t->ch[d] = p;
     86             p->parent = t;
     87             update(t);
     88             update(p);//真逗,什么都不要 
     89        } 
     90        //将t旋转到根 
     91        void splay(Node *t){
     92             //标记下传 
     93             int cnt = 1;
     94             tmp[0] = t;
     95             for (Node *y = t; !is_root(y); y = y->parent) tmp[cnt++] = y->parent;
     96             while (cnt) pushdown(tmp[--cnt]);
     97             
     98             while (!is_root(t)){
     99                   Node *y = t->parent;
    100                   if (is_root(y)) rotate(t, (y->ch[0] == t));
    101                   else {
    102                        int d = (y->parent->ch[0] == y);
    103                        if (y->ch[d] == t) rotate(t, d ^ 1);
    104                        else rotate(y, d);
    105                        rotate(t, d);
    106                   }
    107                   update(t);
    108             }
    109             update(t);
    110        }
    111        Node* access(Node *t){
    112             Node *p = null;
    113             while (t != null){
    114                   splay(t);
    115                   if (p != null) p->parent = t;
    116                   t->ch[1] = p;
    117                   update(t);
    118                   p = t;
    119                   t = t->parent;
    120             }
    121             return p;
    122        }
    123        //合并u,v所在的树 
    124        void merge(Node *u, Node *v){
    125             access(u);
    126             splay(u);
    127             u->delta = 1;
    128             u->parent = v;
    129             return; 
    130        }
    131        void cut(Node *u, Node *v){
    132             access(u)->delta ^= 1;
    133             //splay(u);//转到顶上就切断v就可以了
    134             access(v);
    135             splay(v);
    136             
    137             v->ch[0]->parent = null;
    138             v->ch[0] = null;
    139             return;
    140        }
    141        //找根 
    142        Node *find(Node *t){
    143             access(t);
    144             splay(t);
    145             while (t->parent != null) t = t->parent;
    146             return t; 
    147        }
    148        bool check(Node *u, Node *v){
    149             while (u->parent != null) u = u->parent;
    150             while (v->parent != null) v = v->parent;
    151             return (u == v);
    152        }
    153        void change(Node *l, int x){
    154             access(l);
    155             splay(l);
    156             l->val = x;
    157             update(l);
    158        }
    159 }splay;
    160 int n, m;
    161 int u[MAXN] , v[MAXN];
    162  
    163 void init(){
    164      splay.init();
    165      scanf("%d", &n);
    166      for (int i = 1; i < n; i++) scanf("%d%d", &u[i], &v[i]);
    167      for (int i = 1; i <= n; i++){
    168          int a;
    169          scanf("%d", &a);
    170          splay.NEW(a);
    171      }
    172      for (int i = 1; i < n; i++) 
    173      splay.merge(splay.node + u[i], splay.node + v[i]);
    174 }
    175 void work(){
    176      int m ;
    177      scanf("%d", &m);
    178      for (int i = 1; i <= m; i++){
    179          char str[10];
    180          scanf("%s", str);
    181          if (str[0] == 'C'){
    182             int l, x;
    183             scanf("%d%d", &l, &x);//将l的值改为x
    184             splay.change(splay.node + l, x);
    185          }else if (str[0] == 'Q'){
    186                int l, r;
    187                scanf("%d%d", &l, &r);
    188                if (str[1] == 'S'){
    189                   splay.access(splay.node + l)->delta ^= 1;//换根 
    190                   splay.access(splay.node + r);
    191                   Link_Cut_Tree::Node *p = splay.find(splay.node + r);
    192                   printf("%d
    ", p->sum);
    193                }else{//求最大值 
    194                   splay.access(splay.node + l)->delta ^= 1;//换根 
    195                   splay.access(splay.node + r);
    196                   Link_Cut_Tree::Node *p = splay.find(splay.node + r);
    197                   printf("%d
    ", p->Max);
    198                }
    199          }
    200      }
    201 }
    202 
    203 int main (){
    204     
    205     init();
    206     work();
    207     return 0;
    208 }
    View Code
  • 相关阅读:
    创建型模式
    react-React深入-一等公民-props-onChange
    [react] React 新手必须知道的 N 件事
    [react] 细数 React 的原罪
    创业一年,苟且偷生
    好书推荐-《人类简史》.md—/Users/zjh/Documents/我的文章/好书推荐-《人类简史》
    社会科学-主题阅读.md—/Users/zjh/Documents/我的文章
    好书推荐-《国富论》-15-09.md—/Users/zjh/Documents
    readme.md—/Users/zjh/Documents/我的文章/[PHP]swoole_server几个进程的分工
    [PHP]Yii2框架的坑.md—/Users/zjh/Documents/我的文章/[PHP]Yii2框架的坑
  • 原文地址:https://www.cnblogs.com/hoskey/p/4342812.html
Copyright © 2020-2023  润新知