zoukankan      html  css  js  c++  java
  • poj 2763 Housewife Wind

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

    题意:

    给出n个节点的一棵树,树上每个边表示走过这条边需要的时间 。有q个询问,人初始在s点。

    有两种操作:

    1. 0 u 表示人从当前点走到u点。 此时输出本次移动需要的时间。

    2. 1 i w 表示把第i条路的权值变为w。

    思路:

    权值在边上的树链剖分+线段树单点更新+线段树成段询问

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <vector>
      6 #include <algorithm>
      7 using namespace std;
      8 #define maxn 100010
      9 #define lson l, m, rt<<1
     10 #define rson m+1, r, rt<<1|1
     11 int n, q, s, tot;
     12 struct Node
     13 {
     14     int to, next;
     15     Node(int t, int n)
     16     {
     17         to = t; next = n;
     18     }
     19     Node(){}
     20 }mp[maxn<<2];
     21 //vector <Node> mp[maxn]; //不能用vector建图
     22 int head[maxn];
     23 void AddEdge(int x, int y)
     24 {
     25     mp[tot].to = y;
     26     mp[tot].next = head[x];
     27     head[x] = tot++;
     28 }
     29 struct Edge
     30 {
     31     int from, to, val;
     32 }e[maxn];
     33 int pos;
     34 int siz[maxn], dep[maxn], top[maxn], fa[maxn], son[maxn], w[maxn], fw[maxn];
     35 long long cnt[maxn<<2];
     36 void PushUp(int rt)
     37 {
     38     cnt[rt] = cnt[rt<<1] + cnt[rt<<1|1];
     39 }
     40 void build(int l, int r, int rt)
     41 {
     42     cnt[rt] = 0;
     43     if(l == r) return;
     44     int m = (l+r)>>1;
     45     build(lson);
     46     build(rson);
     47     PushUp(rt);
     48 }
     49 void update(int p, int val, int l, int r, int rt)
     50 {
     51     if(l == r)
     52     {
     53         cnt[rt] = val; return;
     54     }
     55     int m = (l+r)>>1;
     56     if(p <= m) update(p, val, lson);
     57     else update(p, val, rson);
     58     PushUp(rt);
     59 }
     60 long long query(int L, int R, int l, int r, int rt)
     61 {
     62     if(L <= l && R >= r)
     63     {
     64         return cnt[rt];
     65     }
     66     long long ret = 0;
     67     int m = (l+r)>>1;
     68     if(L <= m) ret += query(L, R, lson);
     69     if(R > m) ret += query(L, R, rson);
     70     return ret;
     71 }
     72 int dfs1(int u, int pre, int deep)
     73 {
     74     siz[u] = 1; fa[u] = pre; dep[u] = deep;
     75     int mmax = 0;
     76    // for(int i = 0; i < mp[u].size(); i++)
     77     for(int i = head[u]; i != -1; i = mp[i].next)
     78     {
     79        // if(mp[u][i].to != pre)
     80         if(mp[i].to != pre)
     81         {
     82             int temp = dfs1(mp[i].to, u, deep+1);
     83             siz[u] += temp;
     84             if(son[u] == -1 || temp >= mmax) son[u] = mp[i].to;        
     85         }
     86     }
     87     return siz[u];
     88 }
     89 void dfs2(int u, int val)
     90 {
     91     top[u] = val;
     92     if(son[u] != -1)
     93     {
     94         w[u] = pos++;
     95         fw[w[u]] = u;
     96         dfs2(son[u], val);
     97     }
     98     else if(son[u] == -1)
     99     {
    100         w[u] = pos++;
    101         fw[w[u]] = u;
    102         return;
    103     }
    104    // for(int i = 0; i < mp[u].size(); i++)
    105     for(int i = head[u]; i != -1; i = mp[i].next)
    106     {
    107         //if(mp[u][i].to != fa[u] && mp[u][i].to != son[u]) dfs2(mp[u][i].to, mp[u][i].to);
    108         if(mp[i].to != fa[u] && mp[i].to != son[u]) dfs2(mp[i].to, mp[i].to);
    109     }
    110 }
    111 long long find(int u, int v)
    112 {
    113     int f1 = top[u], f2 = top[v];
    114     long long temp = 0;
    115     while(f1 != f2)
    116     {
    117         if(dep[f1] < dep[f2])
    118         {
    119             swap(f1, f2);
    120             swap(u, v);
    121         }
    122         temp += query(w[f1], w[u], 1, pos-1, 1);
    123         u = fa[f1]; f1 = top[u];
    124     }
    125     if(u == v) return temp;
    126     if(dep[u] > dep[v]) swap(u, v);
    127     temp += query(w[son[u]], w[v], 1, pos-1, 1);
    128     return temp;
    129 }
    130 int main() 
    131 {
    132     //freopen("in.txt", "r", stdin);
    133     //freopen("out.txt", "w", stdout);
    134     while(~scanf("%d%d%d", &n, &q, &s))
    135     {
    136        // for(int i = 1; i <= n; i++) mp[i].clear();
    137         pos = 0; tot = 0; memset(son, -1, sizeof(son));
    138         memset(head, -1, sizeof(head));
    139         
    140         for(int i = 1; i <= n-1; i++)
    141         {
    142             scanf("%d%d%d", &e[i].from, &e[i].to, &e[i].val);
    143             AddEdge(e[i].from, e[i].to);
    144             AddEdge(e[i].to, e[i].from);
    145            // mp[e[i].from].push_back(Node(e[i].to, e[i].val));
    146            // mp[e[i].to].push_back(Node(e[i].from, e[i].val));
    147         }
    148         dfs1(1, -1, 1);
    149         dfs2(1, 1);
    150         build(1, pos-1, 1);
    151         
    152         for(int i = 1; i <= n-1; i++)
    153         {
    154             if(dep[e[i].from] > dep[e[i].to])
    155             {
    156                 swap(e[i].from, e[i].to);
    157             }
    158             update(w[e[i].to], e[i].val, 1, pos-1, 1);
    159         }
    160         while(q--)
    161         {
    162             int op; scanf("%d", &op);
    163             if(op == 0)
    164             {
    165                 int u; scanf("%d", &u);
    166                 printf("%lld
    ", find(s, u));
    167                 s = u;
    168             }
    169             else if(op == 1)
    170             {
    171                 int i, ww; scanf("%d%d", &i, &ww);
    172                 update(w[e[i].to], ww, 1, pos-1, 1);
    173             }
    174         }
    175     }
    176     return 0;
    177 }
  • 相关阅读:
    Makefile 跟着走快点
    MariaDB 复合语句和优化套路
    Unity Shader常用函数,标签,指令,宏总结(持续更新)
    ThreadLocal 简述
    Java全排列排序
    Thrift入门
    Nginx + Keepalived 双机热备
    Linux 虚拟IP
    Java 反编译
    Spring拦截器
  • 原文地址:https://www.cnblogs.com/titicia/p/4902402.html
Copyright © 2011-2022 走看看