• POJ 2763 Housewife Wind (树链剖分 有修改单边权)


    题目链接:http://poj.org/problem?id=2763

    n个节点的树上知道了每条边权,然后有两种操作:0操作是输出 当前节点到 x节点的最短距离,并移动到 x 节点位置;1操作是第i条边的边权变成x。

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

      1 //#pragma comment(linker, "/STACK:102400000,102400000")
      2 #include <iostream>
      3 #include <cstdio>
      4 #include <cstring>
      5 using namespace std;
      6 const int MAXN = 1e5 + 5;
      7 struct EDGE {
      8     int next, to, cost;
      9 }edge[MAXN << 2];
     10 int head[MAXN], tot;
     11 int from[MAXN], to[MAXN], cost[MAXN];
     12 int par[MAXN], dep[MAXN], son[MAXN], size[MAXN];
     13 int top[MAXN], id[MAXN], cnt;
     14 
     15 void init() {
     16     cnt = tot = 0;
     17     memset(head, -1, sizeof(head));
     18 }
     19 
     20 inline void add(int u, int v, int cost) {
     21     edge[tot].next = head[u];
     22     edge[tot].to = v;
     23     head[u] = tot++;
     24 }
     25 
     26 void dfs1(int u, int p, int d) {
     27     dep[u] = d, par[u] = p, size[u] = 1, son[u] = u;
     28     for(int i = head[u]; ~i; i = edge[i].next) {
     29         int v = edge[i].to;
     30         if(v == p)
     31             continue;
     32         dfs1(v, u, d + 1);
     33         if(size[v] >= size[son[u]])
     34             son[u] = v;
     35         size[u] += size[v];
     36     }
     37 }
     38 
     39 void dfs2(int u, int p, int t) {
     40     top[u] = t, id[u] = ++cnt;
     41     if(son[u] != u)
     42         dfs2(son[u], u, t);
     43     for(int i = head[u]; ~i; i = edge[i].next) {
     44         int v = edge[i].to;
     45         if(v == son[u] || v == p)
     46             continue;
     47         dfs2(v, u, v);
     48     }
     49 }
     50 
     51 struct segtree {
     52     int l, r, val;
     53 }T[MAXN << 2];
     54 
     55 void build(int p, int l, int r) {
     56     int mid = (l + r) >> 1;
     57     T[p].l = l , T[p].r = r;
     58     if(l == r) {
     59         return ;
     60     }
     61     build(p << 1, l, mid);
     62     build((p << 1)|1, mid + 1, r);
     63 }
     64 
     65 void updata(int p, int pos, int num) {
     66     int mid = (T[p].l + T[p].r) >> 1;
     67     if(T[p].l == T[p].r && T[p].l == pos) {
     68         T[p].val = num;
     69         return ;
     70     }
     71     if(pos <= mid) {
     72         updata(p << 1, pos, num);
     73     }
     74     else {
     75         updata((p << 1)|1, pos, num);
     76     }
     77     T[p].val = T[p << 1].val + T[(p << 1)|1].val;
     78 }
     79 
     80 int query(int p, int l, int r) {
     81     int mid = (T[p].l + T[p].r) >> 1;
     82     if(l == T[p].l && T[p].r == r) {
     83         return T[p].val;
     84     }
     85     if(r <= mid) {
     86         return query(p << 1, l, r);
     87     }
     88     else if(l > mid) {
     89         return query((p << 1)|1, l, r);
     90     }
     91     else {
     92         return query(p << 1, l, mid) + query((p << 1)|1, mid + 1, r);
     93     }
     94 }
     95 
     96 int find(int u, int v) {
     97     int fu = top[u], fv = top[v], res = 0;
     98     while(fv != fu) {
     99         if(dep[fu] > dep[fv]) {
    100             res += query(1, id[fu], id[u]);
    101             u = par[fu];
    102             fu = top[u];
    103         }
    104         else {
    105             res += query(1, id[fv], id[v]);
    106             v = par[fv];
    107             fv = top[v];
    108         }
    109     }
    110     if(v == u)
    111         return res;
    112     else if(dep[u] > dep[v])
    113         return res + query(1, id[son[v]], id[u]);
    114     else
    115         return res + query(1, id[son[u]], id[v]);
    116 }
    117 
    118 int main()
    119 {
    120     int n, m, root;
    121     while(~scanf("%d %d %d", &n, &m, &root)) {
    122         init();
    123         for(int i = 1; i < n; ++i) {
    124             scanf("%d %d %d", from + i, to + i, cost + i);
    125             add(from[i], to[i], cost[i]);
    126             add(to[i], from[i], cost[i]);
    127         }
    128         dfs1(1, 1, 0);
    129         dfs2(1, 1, 1);
    130         build(1, 1, cnt);
    131         for(int i = 1; i < n; ++i) {
    132             if(dep[from[i]] < dep[to[i]])
    133                 swap(from[i], to[i]);
    134             updata(1, id[from[i]], cost[i]);
    135         }
    136         int op, pos, num;
    137         while(m--) {
    138             scanf("%d", &op);
    139             if(op) {
    140                 scanf("%d %d", &pos, &num);
    141                 updata(1, id[from[pos]], num);
    142             }
    143             else {
    144                 scanf("%d", &pos);
    145                 printf("%d
    ", find(root, pos));
    146                 root = pos;
    147             }
    148         }
    149     }
    150 }
  • 相关阅读:
    每一个合格的家庭主妇都是生产厂长的有力竞争者
    单点登录在ASP.NET上的简单实现
    Asp.net(C#)给图片加上水印效果
    Asp.net Ajax框架教程
    记入cookie一个ip一天只弹一次的弹窗代码JavaScript实例教程
    【转】ASP.net2。0中解决无法获取 GridView 隐藏列值问题
    javascript 动态添加表格行
    IndexOf方法,LastIndexOf方法,substring方法
    SQL 批量插入数据
    js 前台找控件(table里找控件)
  • 原文地址:https://www.cnblogs.com/Recoder/p/5519607.html
Copyright © 2020-2023  润新知