zoukankan      html  css  js  c++  java
  • POJ 2763:Housewife Wind(树链剖分)

    http://poj.org/problem?id=2763

    题意:给出 n 个点, n-1 条带权边, 询问是询问 s 到 v 的权值, 修改是修改存储时候的第 i 条边的权值。

    思路:树链剖分之修改边权。边权的修改, 与点权修改不同的地方在于, 线段树中存的点是边,其中每条边边是以 儿子 的时间戳来记录的。例如: u -> v , dep[u] < dep[v], 说明 u 是 v 的父亲,所以这条边在线段树中的编号就是以 tid[v].

      1 #include <cstdio>
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <cstring>
      5 #include <string>
      6 #include <cmath>
      7 #include <queue>
      8 #include <vector>
      9 using namespace std;
     10 #define N 100005
     11 #define INF 0x3f3f3f3f
     12 #define lson rt<<1, l, m
     13 #define rson rt<<1|1, m+1, r
     14 struct node
     15 {
     16     int v, w, next;
     17 }edge[N*2];
     18 int head[N], tot;
     19 int time, tid[N], fa[N], rak[N], son[N], dep[N], size[N], top[N];
     20 int tree[N<<2];
     21 int e[N][3];
     22 
     23 /*
     24 树链剖分: 边权的修改, 与点权修改不同的地方在于, 线段树中存的点是边,
     25 其中每条边边是以 儿子 的时间戳来记录的
     26 例如: u -> v , dep[u] < dep[v], 说明 u 是 v 的父亲,
     27 所以这条边在线段树中的编号就是以 tid[v] 的形式来存储.
     28 */
     29 
     30 void init()
     31 {
     32     memset(head, -1, sizeof(head));
     33     memset(son, -1, sizeof(son));
     34     memset(fa, 0, sizeof(fa));
     35     time = tot = 0;
     36 }
     37 
     38 void add(int u, int v, int w)
     39 {
     40     edge[tot].next = head[u]; edge[tot].v = v; edge[tot].w = w; head[u] = tot++;
     41 }
     42 
     43 void dfs1(int u, int f, int d)
     44 {
     45     size[u] = 1;
     46     dep[u] = d;
     47     fa[u] = f;
     48     for(int i = head[u]; ~i; i = edge[i].next) {
     49         int v = edge[i].v;
     50         if(v == f) continue;
     51         dfs1(v, u, d + 1);
     52         size[u] += size[v];
     53         if(son[u] == -1 || size[son[u]] < size[v])
     54             son[u] = v;
     55     }
     56 }
     57 
     58 void dfs2(int u, int f)
     59 {
     60     tid[u] = ++time;
     61     top[u] = f;
     62     rak[time] = u;
     63     if(son[u] == -1) return ;
     64     dfs2(son[u], f);
     65     for(int i = head[u]; ~i; i = edge[i].next) {
     66         int v = edge[i].v;
     67         if(v != son[u] && v != fa[u]) {
     68             dfs2(v, v);
     69         }
     70     }
     71 }
     72 
     73 void build(int rt, int l, int r)
     74 {
     75     tree[rt] = 0;
     76     if(l == r) return ;
     77     int m = (l + r) >> 1;
     78     build(lson); build(rson);
     79 }
     80 
     81 void pushup(int rt)
     82 {
     83     tree[rt] = tree[rt<<1] + tree[rt<<1|1];
     84 }
     85 
     86 void update(int rt, int l, int r, int id, int w)
     87 {
     88     if(l == id && r == id) {
     89         tree[rt] = w;
     90         return ;
     91     }
     92     if(l == r) return ;
     93     int m = (l + r) >> 1;
     94     if(id <= m) update(lson, id, w);
     95     else  update(rson, id, w);
     96     pushup(rt);
     97 }
     98 
     99 long long query(int rt, int l, int r, int L, int R)
    100 {
    101     long long  ans = 0;
    102     if(L <= l && r <= R) {
    103         ans += tree[rt];
    104         return ans;
    105     }
    106     int m = (l + r) >> 1;
    107     if(L <= m) ans += query(lson, L, R);
    108     if(m < R) ans += query(rson, L, R);
    109     return ans;
    110 }
    111 
    112 long long change(int u, int v)
    113 {
    114     long long ans = 0;
    115     int tp1 = top[u], tp2 = top[v];
    116     while(top[u] != top[v]) {
    117         if(dep[top[u]] < dep[top[v]]) swap(u, v);
    118         ans += query(1, 1, time, tid[top[u]], tid[u]);
    119         u = fa[top[u]];
    120     }
    121     if(dep[u] > dep[v]) swap(u, v);
    122     if(u == v) return ans; // 如果是同一个点, 就不能继续询问了
    123     ans += query(1, 1, time, tid[son[u]], tid[v]);
    124     return ans;
    125 }
    126 
    127 int main()
    128 {
    129     int n, q, s;
    130     scanf("%d%d%d", &n, &q, &s);
    131     init();
    132     for(int i = 1; i < n; i++) {
    133         int u, v, w;
    134         scanf("%d%d%d", &u, &v, &w);
    135         e[i][0] = u, e[i][1] = v, e[i][2] = w;
    136         add(u, v, w); add(v, u, w);
    137     }
    138     dfs1(s, s, 1);
    139     dfs2(s, s);
    140     build(1, 1, time);
    141     for(int i = 1; i < n; i++) {
    142         if(dep[e[i][0]] > dep[e[i][1]]) swap(e[i][0], e[i][1]);
    143         update(1, 1, time, tid[e[i][1]], e[i][2]);
    144     }
    145     for(int i = 0; i < q; i++) {
    146         int o, a, b;
    147         scanf("%d", &o);
    148         if(o == 1) {
    149             scanf("%d%d", &a, &b);
    150             update(1, 1, time, tid[e[a][1]], b);
    151         } else {
    152             scanf("%d", &a);
    153             long long ans = change(s, a);
    154             s = a;
    155             printf("%lld
    ", ans);
    156         }
    157     }
    158     return 0;
    159 }
    160 
    161 /*
    162 4 4 1
    163 1 2 1
    164 2 3 2
    165 1 4 1
    166 0 2
    167 1 2 3
    168 0 3
    169 0 4
    170 */
  • 相关阅读:
    爬虫框架scrapy(1)持久化存储的多种方式及多页爬取数据
    爬虫之selenium
    redis相关
    爬虫之数据解析
    爬虫之requests模块2
    爬虫之requests模块
    HTTP和HTTPS协议
    Pymongo使用
    MongoDB
    python网络编程之黏包问题
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6013848.html
Copyright © 2011-2022 走看看