zoukankan      html  css  js  c++  java
  • POJ 2763 树链剖分 线段树 Housewife Wind

    单个边的权值修改以及询问路径上的权值之和。

    数据量比较大,用vector存图会超时的。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <vector>
      6 using namespace std;
      7 
      8 void scan(int& x)
      9 {
     10     x = 0;
     11     int ch = ' ';
     12     while(ch < '0' || ch > '9') ch = getchar();
     13     while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
     14 }
     15 
     16 int n, Q, s;
     17 
     18 const int maxn = 100000 + 10;
     19 int u[maxn], v[maxn], d[maxn];
     20 
     21 struct Edge
     22 {
     23     int v, nxt;
     24 };
     25 
     26 int cnt;
     27 int head[maxn];
     28 Edge edge[maxn * 2];
     29 
     30 void AddEdge(int u, int v)
     31 {
     32     edge[cnt].v = v;
     33     edge[cnt].nxt = head[u];
     34     head[u] = cnt++;
     35 }
     36 
     37 int tot;
     38 int L[maxn];
     39 int fa[maxn];
     40 int sz[maxn];
     41 int son[maxn];
     42 int id[maxn];
     43 int top[maxn];
     44 
     45 void dfs(int u)
     46 {
     47     sz[u] = 1; son[u] = 0;
     48     for(int i = head[u]; i != -1; i = edge[i].nxt)
     49     {
     50         int v = edge[i].v;
     51         if(v == fa[u]) continue;
     52         fa[v] = u;
     53         L[v] = L[u] + 1;
     54         dfs(v);
     55         sz[u] += sz[v];
     56         if(sz[v] > sz[son[u]]) son[u] = v;
     57     }
     58 }
     59 
     60 void dfs2(int u, int tp)
     61 {
     62     top[u] = tp;
     63     if(son[u]) { id[son[u]] = ++tot; dfs2(son[u], tp); }
     64     for(int i = head[u]; i != -1; i = edge[i].nxt)
     65     {
     66         int v = edge[i].v;
     67         if(v == fa[u] || v == son[u]) continue;
     68         id[v] = ++tot;
     69         dfs2(v, v);
     70     }
     71 }
     72 
     73 int sum[maxn << 2];
     74 
     75 void update(int o, int L, int R, int p, int v)
     76 {
     77     if(L == R) { sum[o] = v; return ; }
     78     int M = (L + R) / 2;
     79     if(p <= M) update(o<<1, L, M, p, v);
     80     else update(o<<1|1, M+1, R, p, v);
     81     sum[o] = sum[o<<1] + sum[o<<1|1];
     82 }
     83 
     84 int query(int o, int L, int R, int qL, int qR)
     85 {
     86     if(qR < L || qL > R) return 0;
     87     if(qL <= L && R <= qR) return sum[o];
     88     int ans = 0;
     89     int M = (L + R) / 2;
     90     ans += query(o<<1, L, M, qL, qR);
     91     ans += query(o<<1|1, M+1, R, qL, qR);
     92     return ans;
     93 }
     94 
     95 int Query(int u, int v)
     96 {
     97     int ans = 0;
     98     int t1 = top[u], t2 = top[v];
     99     while(t1 != t2)
    100     {
    101         if(L[t1] < L[t2]) { swap(u, v); swap(t1, t2); }
    102         ans += query(1, 1, tot, id[t1], id[u]);
    103         u = fa[t1]; t1 = top[u];
    104     }
    105     if(u == v) return ans;
    106     if(L[u] < L[v]) swap(u, v);
    107     ans += query(1, 1, tot, id[son[v]], id[u]);
    108     return ans;
    109 }
    110 
    111 int main()
    112 {
    113     while(scanf("%d%d%d", &n, &Q, &s) == 3)
    114     {
    115         memset(head, -1, sizeof(head));
    116         cnt = 0;
    117         for(int i = 1; i < n; i++)
    118         {
    119             scan(u[i]); scan(v[i]); scan(d[i]);
    120             AddEdge(u[i], v[i]);
    121             AddEdge(v[i], u[i]);
    122         }
    123 
    124         L[1] = fa[1] = 0;
    125         dfs(1);
    126         tot = 0;
    127         dfs2(1, 1);
    128 
    129         memset(sum, 0, sizeof(sum));
    130         for(int i = 1; i < n; i++)
    131         {
    132             if(L[u[i]] < L[v[i]]) swap(u[i], v[i]);
    133             update(1, 1, tot, id[u[i]], d[i]);
    134         }
    135 
    136         int op, x, y;
    137         while(Q--)
    138         {
    139             scan(op);
    140             if(op == 0)
    141             {
    142                 scan(x);
    143                 printf("%d
    ", Query(s, x));
    144                 s = x;
    145             }
    146             else
    147             {
    148                 scan(x); scan(y);
    149                 update(1, 1, tot, id[u[x]], y);
    150             }
    151         }
    152     }
    153 
    154     return 0;
    155 }
    代码君
  • 相关阅读:
    枚举类型总结
    正则表达式-Java
    java中Mongo
    cookie
    xsd解析
    水平分表的实现
    c#位运算小例子笔记
    c#设计模式之观察者模式(Observer Pattern)
    c#设计模式之代理模式(Proxy Pattern)
    .Net 数据缓存浅析
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4708023.html
Copyright © 2011-2022 走看看