zoukankan      html  css  js  c++  java
  • HDU 3966:Aragorn's Story(树链剖分)

    http://acm.hdu.edu.cn/showproblem.php?pid=3966

    题意:有n个点n-1条边,每个点有一个权值,有两种操作:询问一个点上权值是多少和修改u到v这条链上的权值。

    思路:树链剖分。学习地址:http://blog.sina.com.cn/s/blog_7a1746820100wp67.html   http://blog.csdn.net/acdreamers/article/details/10591443

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cmath>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 #include <string>
      7 #include <iostream>
      8 #include <stack>
      9 #include <map>
     10 #include <queue>
     11 using namespace std;
     12 #define N 50010
     13 #define INF 0x3f3f3f3f
     14 #define lson rt<<1, l, m
     15 #define rson rt<<1|1, m+1, r
     16 struct node
     17 {
     18     int u, v, next;
     19 }edge[N*2];
     20 int tot, head[N]; //存边部分
     21 int tim, son[N], tid[N], fa[N], depth[N], size[N], top[N], num[N], rak[N]; //树剖部分
     22 //分别对应DFS的时间、重儿子、节点的时间戳、父节点、节点深度、该节点的子树的节点数、树链中的头节点、初始节点权值、rak[i]表示时间戳为i的节点是rak[i](在线段树中的位置)
     23 int tree[N<<2], col[N<<2]; //线段树部分
     24 int n;
     25 
     26 void init()
     27 {
     28     tim = tot = 0;
     29     memset(head, -1, sizeof(head));
     30     memset(son, -1, sizeof(son));
     31 }
     32 
     33 void add(int u, int v)
     34 {
     35     edge[tot].next = head[u]; edge[tot].u = u; edge[tot].v = v; head[u] = tot++;
     36 }
     37 
     38 void dfs1(int u, int f, int d)
     39 {
     40     size[u] = 1;
     41     depth[u] = d;
     42     fa[u] = f;
     43     for(int i = head[u]; ~i; i = edge[i].next) {
     44         int v = edge[i].v; 
     45         if(f == v) continue;
     46         dfs1(v, u, d + 1);
     47         if(size[v] > size[son[u]] || son[u] == -1) son[u] = v;
     48         size[u] += size[v];
     49     }
     50 }
     51 
     52 void dfs2(int u, int f)
     53 {
     54     top[u] = f;
     55     tid[u] = ++tim;
     56     rak[tid[u]] = u;
     57     if(son[u] == -1) return ;
     58     dfs2(son[u], f); //是重儿子的话
     59     for(int i = head[u]; ~i; i = edge[i].next) {
     60         int v = edge[i].v;
     61         if(v != son[u] && v != fa[u]) dfs2(v, v); //不是重儿子的话
     62     }
     63 }
     64 
     65 void PushDown(int rt, int len)
     66 {
     67     if(col[rt]) {
     68         col[rt<<1] += col[rt];
     69         col[rt<<1|1] += col[rt];
     70         tree[rt<<1] += (len - (len >> 1)) * col[rt];
     71         tree[rt<<1|1] += (len >> 1) * col[rt];
     72         col[rt] = 0;
     73     }
     74 }
     75 
     76 void Build(int rt, int l, int r)
     77 {
     78     col[rt] = 0;
     79     tree[rt] = 0;
     80     if(l == r) {
     81         tree[rt] = num[rak[l]];
     82         return ;
     83     }
     84     int m = (l + r) >> 1;
     85     Build(lson);
     86     Build(rson);
     87 }
     88 
     89 void Update(int rt, int l, int r, int L, int R, int val)
     90 {
     91     if(L <= l && r <= R) {
     92         col[rt] += val;
     93         tree[rt] += val * (r - l + 1);
     94         return ;
     95     }
     96     PushDown(rt, r - l + 1);
     97     int m = (l + r) >> 1;
     98     if(L <= m) Update(lson, L, R, val);
     99     if(R > m) Update(rson, L, R, val);
    100 }
    101 
    102 int Query(int rt, int l, int r, int id)
    103 {
    104     if(l == r && l == id) return tree[rt];
    105     PushDown(rt, r - l + 1);
    106     int m = (l + r) >> 1;
    107     if(id <= m) return Query(lson, id);
    108     else return Query(rson, id);
    109 }
    110 
    111 void Change(int u, int v, int val)
    112 {
    113     while(top[u] != top[v]) {
    114         if(depth[top[u]] < depth[top[v]]) swap(u, v);
    115         Update(1, 1, n, tid[top[u]], tid[u], val); //父节点编号小
    116         u = fa[top[u]]; //!!!
    117     }
    118     if(depth[u] > depth[v]) swap(u, v);
    119     Update(1, 1, n, tid[u], tid[v], val);
    120 }
    121 
    122 int main()
    123 {
    124     int m, q, id, u, v, val;
    125     char s[2];
    126     while(~scanf("%d%d%d", &n, &m, &q)) {
    127         init();
    128         for(int i = 1; i <= n; i++) scanf("%d", &num[i]);
    129         for(int i = 0; i < m; i++) {
    130             scanf("%d%d", &u, &v);
    131             add(u, v); add(v, u);
    132         }
    133         dfs1(1, -1, 1    );
    134         dfs2(1, 1);
    135         Build(1, 1, n);
    136         while(q--) {
    137             scanf("%s", s);
    138             if(s[0] == 'Q') {
    139                 scanf("%d", &id);
    140                 printf("%d
    ", Query(1, 1, n, tid[id]));
    141             } else {
    142                 scanf("%d%d%d", &u, &v, &val);
    143                 if(s[0] == 'D') val = -val;
    144                 Change(u, v, val);
    145             }
    146         }
    147     }
    148     return 0;
    149 }
  • 相关阅读:
    基于Flask开发web微信
    爬取实例
    scrapy框架学习之路
    scripy
    wtforms
    由testcase数据之分析
    无用之flask学习
    无用之flask
    无用之学matplotlib,numpy,pandas
    jsp_1
  • 原文地址:https://www.cnblogs.com/fightfordream/p/5941779.html
Copyright © 2011-2022 走看看