zoukankan      html  css  js  c++  java
  • SPOJ 375 (树链剖分

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=28982#problem/I

    给你一棵有边权的树,有两个操作:一个操作是输出l到r点之间的最大的边权,另一个操作是修改某条边的权值。

    这题是树链剖分的简单模版题,代码如下:

      1 //修改单边权
      2 #include <iostream>
      3 #include <cstdio>
      4 #include <cstring>
      5 using namespace std;
      6 const int MAXN = 1e4 + 10;
      7 struct data {
      8     int next , to , cost;
      9 }edge[MAXN << 1];
     10 int head[MAXN] , top[MAXN] , id[MAXN] , par[MAXN] , dep[MAXN] , size[MAXN] , son[MAXN];
     11 int cnt , tot , v[MAXN] , u[MAXN] , cost[MAXN];
     12 
     13 void init() {
     14     cnt = tot = 0;
     15     memset(head , -1 , sizeof(head));
     16 }
     17 
     18 inline void add(int u , int v , int cost) {
     19     edge[cnt].next = head[u];
     20     edge[cnt].to = v;
     21     edge[cnt].cost = cost;
     22     head[u] = cnt++;
     23 }
     24 
     25 void dfs_1(int u , int p , int d) {
     26     dep[u] = d , par[u] = p , size[u] = 1 , son[u] = u;
     27     for(int i = head[u] ; ~i ; i = edge[i].next) {
     28         int v = edge[i].to;
     29         if(v == p)
     30             continue;
     31         dfs_1(v , u , d + 1);
     32         if(size[son[u]] < size[v])
     33             son[u] = v;
     34         size[u] += size[v];
     35     }
     36 }
     37 
     38 void dfs_2(int u , int p , int t) {
     39     top[u] = t , id[u] = ++tot;
     40     if(son[u] != u)
     41         dfs_2(son[u] , u , t);
     42     for(int i = head[u] ; ~i ; i = edge[i].next) {
     43         int v = edge[i].to;
     44         if(v == p || v == son[u]) 
     45             continue;
     46         dfs_2(v , u , v);
     47     }
     48 }
     49 
     50 struct segtree {
     51     int l , r , Max;
     52 }T[MAXN << 2];
     53 
     54 void build(int p , int l , int r) {
     55     int mid = (l + r) >> 1;
     56     T[p].l = l , T[p].r = r;
     57     if(l == r)
     58         return ;
     59     build(p << 1 , l , mid);
     60     build((p << 1)|1 , mid + 1 , r);
     61 }
     62 
     63 void updata(int p , int pos , int num) {
     64     int mid = (T[p].l + T[p].r) >> 1;
     65     if(T[p].l == T[p].r) {
     66         T[p].Max = num;
     67         return ;
     68     }
     69     if(pos <= mid)
     70         updata(p << 1 , pos , num);
     71     else
     72         updata((p << 1)|1 , pos , num);
     73     T[p].Max = max(T[p << 1].Max , T[(p << 1)|1].Max);
     74 }
     75 
     76 int query(int p , int l , int r) {
     77     int mid = (T[p].l + T[p].r) >> 1;
     78     if(l == T[p].l && T[p].r == r)
     79         return T[p].Max;
     80     if(r <= mid)
     81         return query(p << 1 , l , r);
     82     else if(l > mid)
     83         return query((p << 1)|1 , l , r);
     84     else
     85         return max(query(p << 1 , l , mid) , query((p << 1)|1 , mid + 1 , r));
     86 }
     87 
     88 int Find(int l , int r) {
     89     int pl = top[l] , pr = top[r] , Max = 0;
     90     while(pl != pr) {
     91         if(dep[pl] > dep[pr]) {
     92             Max = max(Max , query(1 , id[pl] , id[l]));
     93             l = par[pl];
     94             pl = top[l];
     95         }
     96         else {
     97             Max = max(Max , query(1 , id[pr] , id[r]));
     98             r = par[pr];
     99             pr = top[r];
    100         }
    101     }
    102     if(r == l)
    103         return Max;
    104     else if(dep[r] > dep[l])
    105         return max(Max , query(1 , id[son[l]] , id[r]));
    106     else 
    107         return max(Max , query(1 , id[son[r]] , id[l]));
    108 }
    109 
    110 int main()
    111 {
    112     int t , n , l , r;
    113     scanf("%d" , &t);
    114     while(t--) {
    115         scanf("%d" , &n);
    116         init();
    117         for(int i = 1 ; i < n ; ++i) {
    118             scanf("%d %d %d" , u + i , v + i , cost + i);
    119             add(u[i] , v[i] , cost[i]);
    120             add(v[i] , u[i] , cost[i]);
    121         }
    122         dfs_1(1 , 1 , 0);
    123         dfs_2(1 , 1 , 1);
    124         build(1 , 1 , tot);
    125         for(int i = 1 ; i < n ; ++i) {
    126             if(dep[u[i]] > dep[v[i]])
    127                 swap(u[i] , v[i]);
    128             updata(1 , id[v[i]] , cost[i]);
    129         }
    130         char q[10];
    131         while(scanf("%s" , q) && q[0] != 'D') {
    132             scanf("%d %d" , &l , &r);
    133             if(q[0] == 'C') {
    134                 updata(1 , id[v[l]] , r);        
    135             }
    136             else {
    137                 printf("%d
    " , Find(l , r));
    138             }
    139         }
    140     }
    141     return 0;
    142 }
  • 相关阅读:
    lambda函数
    linux 自学系列:wc命令
    linux 自学系列:chmod 权限操作
    linux 自学系列:创建、删除目录、移动、更名文件或目录
    linux 自学系列:vi、vim编辑工具
    《架构之美》学习随笔:设计第一步
    安装memcache 时提示error while loading shared libraries: libevent2.0解决办法
    《架构之美》学习随笔:保证质量
    linux 自学系列:环境变量设置
    logging模块学习笔记:logger 对象、日志等级
  • 原文地址:https://www.cnblogs.com/Recoder/p/5515548.html
Copyright © 2011-2022 走看看