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\n", 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 }

 

posted @ 2015-10-22 18:44  下周LGD该赢了吧  阅读(137)  评论(0编辑  收藏  举报