zoukankan      html  css  js  c++  java
  • FZU 2082 过路费 (树链剖分 修改单边权)

    题目链接:http://acm.fzu.edu.cn/problem.php?pid=2082

    树链剖分模版题,求和,修改单边权。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <algorithm>
      4 #include <cstring>
      5 using namespace std;
      6 typedef long long LL;
      7 const int MAXN = 5e4 + 10;
      8 struct EDGE {
      9     int to , next;
     10     LL cost;
     11 }edge[MAXN << 1];
     12 int from[MAXN] , to[MAXN] , head[MAXN] , cnt , tot;
     13 LL cost[MAXN] , val[MAXN] , dis[MAXN];
     14 int top[MAXN] , dep[MAXN] , size[MAXN] , son[MAXN] , par[MAXN] , id[MAXN];
     15 
     16 void init() {
     17     memset(head , -1 , sizeof(head));
     18     cnt = tot = 0;
     19 }
     20 
     21 inline void add(int u , int v , LL cost) {
     22     edge[tot].next = head[u];
     23     edge[tot].to = v;
     24     edge[tot].cost = cost;
     25     head[u] = tot++;
     26 }
     27 
     28 void dfs1(int u , int p , int d) {
     29     dep[u] = d , par[u] = p , size[u] = 1 , son[u] = u;
     30     for(int i = head[u] ; ~i ; i = edge[i].next) {
     31         int v = edge[i].to;
     32         if(v == p)
     33             continue;
     34         dfs1(v , u , d + 1);
     35         if(size[v] > size[son[u]])
     36             son[u] = v;
     37         size[u] += size[v];
     38     }
     39 }
     40 
     41 void dfs2(int u , int p , int t) {
     42     top[u] = t , id[u] = ++cnt;
     43     if(son[u] != u)
     44         dfs2(son[u] , u , t);
     45     for(int i = head[u] ; ~i ; i = edge[i].next) {
     46         int v = edge[i].to;
     47         if(v == son[u] || v == p)
     48             continue;
     49         dfs2(v , u , v);
     50     }
     51 }
     52 
     53 struct SegTree {
     54     int l , r;
     55     LL sum;
     56 }T[MAXN << 2];
     57 
     58 void build(int p , int l , int r) {
     59     int mid = (l + r) >> 1;
     60     T[p].l = l , T[p].r = r;
     61     if(l == r) {
     62         T[p].sum = val[l];
     63         return ;
     64     }
     65     build(p << 1 , l , mid);
     66     build((p << 1)|1 , mid + 1 , r);
     67     T[p].sum = T[p << 1].sum + T[(p << 1)|1].sum;
     68 }
     69 
     70 void updata(int p , int pos , LL num) {
     71     int mid = (T[p].l + T[p].r) >> 1;
     72     if(T[p].l == T[p].r && T[p].l == pos) {
     73         T[p].sum = num;
     74         return ;
     75     }
     76     if(pos <= mid) {
     77         updata(p << 1 , pos , num);
     78     }
     79     else {
     80         updata((p << 1)|1 , pos , num);
     81     }
     82     T[p].sum = T[p << 1].sum + T[(p << 1)|1].sum;
     83 }
     84 
     85 LL query(int p , int l , int r) {
     86     int mid = (T[p].l + T[p].r) >> 1;
     87     if(T[p].l == l && T[p].r == r) {
     88         return T[p].sum;
     89     }
     90     if(r <= mid) {
     91         return query(p << 1 , l , r);
     92     }
     93     else if(l > mid) {
     94         return query((p << 1)|1 , l , r);
     95     }
     96     else {
     97         return query(p << 1 , l , mid) + query((p << 1)|1 , mid + 1 , r);
     98     }
     99 }
    100 
    101 LL Find(int u , int v) {
    102     int fu = top[u] , fv = top[v];
    103     LL res = 0;
    104     while(fu != fv) {
    105         if(dep[fu] >= dep[fv]) {
    106             res += query(1 , id[fu] , id[u]);
    107             u = par[fu];
    108             fu = top[u];
    109         }
    110         else {
    111             res += query(1 , id[fv] , id[v]);
    112             v = par[fv];
    113             fv = top[v];
    114         }
    115     }
    116     if(v == u)
    117         return res;
    118     else if(dep[u] > dep[v])
    119         return res + query(1 , id[son[v]] , id[u]);
    120     else 
    121         return res + query(1 , id[son[u]] , id[v]);
    122 }
    123 
    124 int main()
    125 {
    126     int n, m , l , r , c;
    127     while(~scanf("%d %d" , &n , &m)) {
    128         init();
    129         for(int i = 1 ; i < n ; ++i) {
    130             scanf("%d %d %lld" , from + i , to + i , cost + i);
    131             add(from[i] , to[i] , cost[i]);
    132             add(to[i] , from[i] , cost[i]);
    133         }
    134         dfs1(1 , 1 , 0);
    135         dfs2(1 , 1 , 1);
    136         //build(1 , 1 , cnt);
    137         for(int i = 1 ; i < n ; ++i) {
    138             if(dep[from[i]] < dep[to[i]])
    139                 swap(from[i] , to[i]);
    140             val[id[from[i]]] = cost[i];
    141             //updata(1 , id[from[i]] , cost[i]);
    142         }
    143         build(1 , 1 , cnt);
    144         while(m--) {
    145             scanf("%d %d %d" , &c , &l , &r);
    146             if(c == 0) {
    147                 updata(1 , id[from[l]] , (LL)r);
    148             }
    149             else {
    150                 printf("%d
    " , Find(l , r));
    151             }
    152         }
    153     }
    154 }
  • 相关阅读:
    3.2.1 正則表達式的语法(1)
    朴素贝叶斯(naive bayes)
    有方向的运动js
    碰撞检測之OBB-OBB的SweepTest
    左右上下都能滚动的效果
    C语言中 fputs() fgets() 的使用方法
    Apache Module mod_ssl
    "ssllabs" website and "testssl" website
    Google发布SSLv3漏洞简要分析报告
    为什么要使用TLSv1.2和System SSL?
  • 原文地址:https://www.cnblogs.com/Recoder/p/5517581.html
Copyright © 2011-2022 走看看