POJ 2763 Housewife Wind 树链剖分

题意:给你一颗树,两个操作,改变某条边的值,求起点到终点路径长度。

解题思路:求值和点略有不同。不过问题不是太大,主要要注意的问题就是 ,用vector 存 链接表 时间太慢了,不如head 存连接表快 ,慢3倍以上

解题代码:

  1 // File Name: spoj375.cpp
  2 // Author: darkdream
  3 // Created Time: 2014年10月09日 星期四 19时50分56秒
  4 
  5 #include<vector>
  6 #include<list>
  7 #include<map>
  8 #include<set>
  9 #include<deque>
 10 #include<stack>
 11 #include<bitset>
 12 #include<algorithm>
 13 #include<functional>
 14 #include<numeric>
 15 #include<utility>
 16 #include<sstream>
 17 #include<iostream>
 18 #include<iomanip>
 19 #include<cstdio>
 20 #include<cmath>
 21 #include<cstdlib>
 22 #include<cstring>
 23 #include<ctime>
 24 //#pragma comment(linker,"/STACK:102400000,102400000")
 25 //#define debug
 26 #define LL long long
 27 #define maxn 100006 
 28 using namespace std;
 29 struct sgnode{
 30     int l,r ;
 31     int mx;
 32 }tr[maxn << 2];
 33 void pushup(int c)
 34 {
 35     tr[c].mx =tr[c<<1].mx + tr[(c<<1)|1].mx;
 36 }
 37 void build(int c, int l ,int r )
 38 {
 39     tr[c].l = l ; 
 40     tr[c].r = r; 
 41     tr[c].mx = 0 ;
 42     if(l ==  r)
 43         return ; 
 44     int m = (l+r)>>1;
 45     build(c<<1,l,m);
 46     build((c<<1)|1,m+1,r);
 47 }
 48 void update(int c, int k,int v)
 49 {
 50     if(tr[c].l == tr[c].r && tr[c].l == k)
 51     {
 52         tr[c].mx = v; 
 53         return;
 54     }
 55     int m = (tr[c].l +tr[c].r) >> 1;
 56     if(k <= m )
 57         update(c<<1,k,v);
 58     else 
 59         update((c<<1)|1,k,v);
 60     pushup(c);
 61 }
 62 int query(int c, int l ,int r)
 63 {
 64     
 65     if(tr[c].l >=  l && tr[c].r <=  r)
 66     {
 67         return tr[c].mx;
 68     }
 69     int m = (tr[c].l + tr[c].r) >> 1;
 70     if(r <= m)
 71      return query(c<<1,l,r);
 72     if(l > m)
 73       return     query((c<<1)|1,l,r);
 74     else  return query(c <<1,l,m) + query((c<<1)|1,m+1,r);
 75 }
 76 struct node{
 77   int to,next;
 78 }mp[maxn*2];
 79 int head[maxn];
 80 int siz[maxn]; // 子节点的个数
 81 int fa[maxn];  // 父亲节点
 82 int son[maxn];  // 儿子节点
 83 int dep[maxn];  // 深度
 84 int top[maxn];  // 
 85 int w[maxn];
 86 int totw,tote;
 87 int n;
 88 void addedge(int u ,int v)
 89 {
 90    mp[tote].to = v ; 
 91    mp[tote].next = head[u];
 92    head[u] = tote ++;; 
 93 }
 94 void dfs_1(int k , int la,int d)
 95 {
 96     //    printf("%d %d %d
",k,la,num);
 97     dep[k] = d; 
 98     fa[k] = la;
 99     siz[k] = 1 ;
100     son[k] = -1;
101     for(int i = head[k] ;i != -1 ;i = mp[i].next)
102     {
103         if(mp[i].to != la)
104         {
105             dfs_1(mp[i].to,k,d+1);
106             siz[k] += siz[mp[i].to];
107             if(son[k] == -1 || siz[mp[i].to] > siz[son[k]])
108                 son[k] = mp[i].to ;
109         }
110     }
111 }
112 void dfs_2(int k,int sp )
113 {
114     top[k] = sp;
115     w[k] = totw ++ ;
116     if(son[k] == -1) return;
117     dfs_2(son[k],sp);
118     for(int i = head[k] ;i != -1 ;i = mp[i].next)
119     {
120         //        printf("%d
",mp[i].to);
121         if(mp[i].to!= son[k] && mp[i].to != fa[k]) 
122             dfs_2(mp[i].to,mp[i].to);           
123     }
124 }
125 void make()
126 {
127     totw = 0 ; 
128     dfs_1(1,0,1);
129     dfs_2(1,1);
130 }
131 struct edges{
132     int u,v,w;
133 }edge[maxn];
134 int find(int u ,int v)
135 {
136     int f1 = top[u],f2 = top[v];
137     int tmp = 0 ;
138     while(f1 != f2)
139     {
140         if(dep[f1] < dep[f2])
141         {
142             swap(f1,f2);
143             swap(u,v);
144         }
145         tmp +=query(1,w[f1],w[u]);
146         u = fa[f1]; // f1 是他的top
147         f1 = top[u];
148     }
149     if(u == v )  return tmp;
150     if(dep[u] > dep[v])
151         swap(u,v);
152     tmp +=query(1,w[son[u]],w[v]);
153     return tmp;
154 }
155 int main(){
156     int q , s;
157 #ifdef debug
158 
159     freopen("out","r",stdin);
160     freopen("2763","w",stdout);
161 
162     int be = clock();
163 #endif
164     int ti = 0;
165     while(scanf("%d %d %d",&n,&q,&s) != EOF)
166     {
167 //    fclose(stdout);
168     //    printf("******%d
",++ti);
169     //freopen("2763","w",stdout);
170         memset(head,-1,sizeof(int)*(n+1));
171         tote = 0 ; 
172         for(int i = 1;i < n ;i ++)
173         {
174         //    printf("***
");
175             scanf("%d %d %d",&edge[i].u,&edge[i].v,&edge[i].w);
176             addedge(edge[i].u,edge[i].v);
177             addedge(edge[i].v,edge[i].u);
178         }
179         make();
180         //printf("***
");
181         build(1,1,totw-1);
182         for(int i = 1;i < n;i ++)
183         {
184             if(dep[edge[i].u] > dep[edge[i].v])
185                 swap(edge[i].u,edge[i].v);
186             //printf("%d %d*
",w[edge[i].v],edge[i].w);
187             update(1,w[edge[i].v],edge[i].w);
188         }
189         int op;
190         int u,v,uv;
191         u = s; 
192         while(q--)
193         {
194                 
195            scanf("%d",&op);
196            if(op == 0 )
197            {
198               scanf("%d",&v);
199         //      printf("****
");
200               printf("%d
",find(u,v));
201               u = v; 
202            }else{
203               scanf("%d %d",&v,&uv);
204               update(1,w[edge[v].v],uv);
205            } 
206         }
207     }
208     //freopen(stdout,"w",stdout);
209 #ifdef debug
210     int en = clock();
211     printf("%d
",en-be);    
212 #endif
213     return 0;
214 }
View Code
原文地址:https://www.cnblogs.com/zyue/p/4425461.html