spoj 375 AND bzoj 1036 树链剖分

树链剖分的入门题目,自己写了下感觉还是挺好写的,不过真的有点长...

spoj 375 边有权值:

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 using namespace std;
  5 
  6 const int INF = -999999999;
  7 const int N = 10001;
  8 int head[N];
  9 int sz[N];
 10 int depth[N];
 11 int num[N];
 12 int top[N];
 13 int dfn[N];
 14 int hc[N];
 15 int fa[N];
 16 int n, e, dfs_clock;
 17 
 18 void init()
 19 {
 20     e = dfs_clock = 0;
 21     memset( head, -1, sizeof(head) );
 22 }
 23 
 24 struct Edge 
 25 {
 26     int v, w, next;
 27 } edge[N << 1];
 28 
 29 void addEdge( int u, int v, int w )
 30 {
 31     edge[e].v = v;
 32     edge[e].w = w;
 33     edge[e].next = head[u];
 34     head[u] = e++;
 35 }
 36 
 37 void dfs1( int u, int pre, int dep )
 38 {
 39     sz[u] = 1;
 40     fa[u] = pre;
 41     depth[u] = dep;
 42     hc[u] = -1;
 43     for ( int i = head[u]; i != -1; i = edge[i].next )
 44     {
 45         int v = edge[i].v;
 46         if ( v == pre ) continue;
 47         dfs1( v, u, dep + 1 );
 48         sz[u] += sz[v];
 49         if ( hc[u] == -1 || sz[v] > sz[hc[u]] )
 50         {
 51             hc[u] = v;
 52         }
 53     }
 54 }
 55 
 56 void dfs2( int u, int tp )
 57 {
 58     top[u] = tp;
 59     dfn[u] = ++dfs_clock;
 60     if ( hc[u] != -1 )
 61     {
 62         dfs2( hc[u], tp );
 63     }
 64     for ( int i = head[u]; i != -1; i = edge[i].next )
 65     {
 66         int v = edge[i].v;
 67         if ( v == fa[u] ) continue;
 68         if ( v == hc[u] )
 69         {
 70             num[dfn[v]] = edge[i].w;
 71         }
 72         else
 73         {
 74             dfs2( v, v );
 75             num[dfn[v]] = edge[i].w;
 76         }
 77     }
 78 }
 79 
 80 struct Node 
 81 {
 82     int l, r, maxn;
 83 } node[N << 2];
 84 
 85 void pushup( int i )
 86 {
 87     node[i].maxn = max( node[i << 1].maxn, node[i << 1 | 1].maxn );
 88 }
 89 
 90 void build( int i, int l, int r )
 91 {
 92     node[i].l = l, node[i].r = r;
 93     if ( l == r )
 94     {
 95         node[i].maxn = num[l];
 96         return ;
 97     }
 98     int mid = ( l + r ) >> 1;
 99     build( i << 1, l, mid );
100     build( i << 1 | 1, mid + 1, r );
101     pushup(i);
102 }
103 
104 void update( int i, int pos, int val )
105 {
106     if ( node[i].l == pos && node[i].r == pos )
107     {
108         node[i].maxn = val;
109         return ;
110     }
111     int mid = ( node[i].l + node[i].r ) >> 1;
112     if ( pos <= mid )
113     {
114         update( i << 1, pos, val );
115     }
116     else
117     {
118         update( i << 1 | 1, pos, val );
119     }
120     pushup(i);
121 }
122 
123 int query( int i, int l, int r )
124 {
125     if ( node[i].l == l && node[i].r == r ) 
126     {
127         return node[i].maxn;
128     }
129     int mid = ( node[i].l + node[i].r ) >> 1;
130     if ( r <= mid )
131     {
132         return query( i << 1, l, r );
133     }
134     else if ( l > mid )
135     {
136         return query( i << 1 | 1, l, r );
137     }
138     else
139     {
140         return max( query( i << 1, l, mid ), query( i << 1 | 1, mid + 1, r ) );
141     }
142 }
143 
144 struct Data
145 {
146     int u, v;
147 } d[N];
148 
149 int tree_query( int x, int y )
150 {
151     int ans = INF;
152     while ( top[x] != top[y] )
153     {
154         if ( depth[top[x]] < depth[top[y]] )
155         {
156             swap( x, y );
157         }
158         ans = max( ans, query( 1, dfn[top[x]], dfn[x] ) );
159         x = fa[top[x]];
160     }
161     if ( x != y )
162     {
163         if ( depth[x] > depth[y] ) swap( x, y );
164         ans = max( ans, query( 1, dfn[x] + 1, dfn[y] ) );
165     }
166     return ans;
167 }
168 
169 void tree_update( int x, int y )
170 {
171     int u = d[x].u, v = d[x].v;
172     if ( depth[u] < depth[v] ) u = v;
173     update( 1, dfn[u], y );
174 }
175 
176 int main ()
177 {
178     int t;
179     scanf("%d", &t);
180     while ( t-- )
181     {
182         scanf("%d", &n);
183         init();
184         for ( int i = 1; i < n; i++ )
185         {
186             int u, v, w;
187             scanf("%d%d%d", &u, &v, &w);
188             addEdge( u, v, w );
189             addEdge( v, u, w );
190             d[i].u = u, d[i].v = v;
191         }
192         dfs1( 1, -1, 1 );
193         dfs2( 1, 1 );
194         build( 1, 2, n );
195         char op[11];
196         int x, y;
197         while ( 1 )
198         {
199             scanf("%s", op);
200             if ( op[0] == 'D' ) break;
201             scanf("%d%d", &x, &y);
202             if ( op[0] == 'Q' )
203             {
204                 printf("%d\n", tree_query( x, y ));
205             }
206             else
207             {
208                 tree_update( x, y );
209             }
210         }
211     }
212     return 0;
213 }

bzoj 1036 点有权值:

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 using namespace std;
  5 
  6 const int INF = -9999999;
  7 const int N = 30001;
  8 int c[N];
  9 int head[N];
 10 int sz[N];
 11 int depth[N];
 12 int num[N];
 13 int top[N];
 14 int dfn[N];
 15 int hc[N];
 16 int fa[N];
 17 int n, e, dfs_clock;
 18 
 19 void init()
 20 {
 21     e = dfs_clock = 0;
 22     memset( head, -1, sizeof(head) );
 23 }
 24 
 25 struct Edge 
 26 {
 27     int v, next;
 28 } edge[N << 1];
 29 
 30 void addEdge( int u, int v )
 31 {
 32     edge[e].v = v;
 33     edge[e].next = head[u];
 34     head[u] = e++;
 35 }
 36 
 37 void dfs1( int u, int pre, int dep )
 38 {
 39     sz[u] = 1;
 40     fa[u] = pre;
 41     depth[u] = dep;
 42     hc[u] = -1;
 43     for ( int i = head[u]; i != -1; i = edge[i].next )
 44     {
 45         int v = edge[i].v;
 46         if ( v == pre ) continue;
 47         dfs1( v, u, dep + 1 );
 48         sz[u] += sz[v];
 49         if ( hc[u] == -1 || sz[v] > sz[hc[u]] )
 50         {
 51             hc[u] = v;
 52         }
 53     }
 54 }
 55 
 56 void dfs2( int u, int tp )
 57 {
 58     top[u] = tp;
 59     dfn[u] = ++dfs_clock;
 60     num[dfn[u]] = c[u];
 61     if ( hc[u] != -1 )
 62     {
 63         dfs2( hc[u], tp );
 64     }
 65     for ( int i = head[u]; i != -1; i = edge[i].next )
 66     {
 67         int v = edge[i].v;
 68         if ( v == fa[u] || v == hc[u] ) continue;
 69         dfs2( v, v );
 70     }
 71 }
 72 
 73 struct Node 
 74 {
 75     int l, r;
 76     int maxn, sum;    
 77 } node[N << 2];
 78 
 79 void pushup( int i )
 80 {
 81     node[i].maxn = max( node[i << 1].maxn, node[i << 1 | 1].maxn );
 82     node[i].sum = node[i << 1].sum + node[i << 1 | 1].sum;
 83 }
 84 
 85 void build( int i, int l, int r )
 86 {
 87     node[i].l = l, node[i].r = r;
 88     if ( l == r )
 89     {
 90         node[i].maxn = node[i].sum = num[l];  
 91         return ;
 92     }
 93     int mid = ( l + r ) >> 1;
 94     build( i << 1, l, mid );
 95     build( i << 1 | 1, mid + 1, r );
 96     pushup(i);
 97 }
 98 
 99 void update( int i, int pos, int val )
100 {
101     if ( node[i].l == pos && node[i].r == pos )
102     {
103         node[i].maxn = node[i].sum = val;
104         return ;
105     }
106     int mid = ( node[i].l + node[i].r ) >> 1;
107     if ( pos <= mid )
108     {
109         update( i << 1, pos, val );
110     }
111     else
112     {
113         update( i << 1 | 1, pos, val );
114     }
115     pushup(i);
116 }
117 
118 int query_max( int i, int l, int r )
119 {
120     if ( node[i].l == l && node[i].r == r ) 
121     {
122         return node[i].maxn;
123     }
124     int mid = ( node[i].l + node[i].r ) >> 1;
125     if ( r <= mid )
126     {
127         return query_max( i << 1, l, r );
128     }
129     else if ( l > mid )
130     {
131         return query_max( i << 1 | 1, l, r );
132     }
133     else
134     {
135         return max( query_max( i << 1, l, mid ), query_max( i << 1 | 1, mid + 1, r ) );
136     }
137 }
138 
139 int query_sum( int i, int l, int r )
140 {
141     if ( node[i].l == l && node[i].r == r ) 
142     {
143         return node[i].sum;
144     }
145     int mid = ( node[i].l + node[i].r ) >> 1;
146     if ( r <= mid )
147     {
148         return query_sum( i << 1, l, r );
149     }
150     else if ( l > mid )
151     {
152         return query_sum( i << 1 | 1, l, r );
153     }
154     else
155     {
156         return query_sum( i << 1, l, mid ) + query_sum( i << 1 | 1, mid + 1, r );
157     }
158 }
159 
160 int tree_query_max( int x, int y )
161 {
162     int ans = INF;
163     while ( top[x] != top[y] )
164     {
165         if ( depth[top[x]] < depth[top[y]] )
166         {
167             swap( x, y );
168         }
169         ans = max( ans, query_max( 1, dfn[top[x]], dfn[x] ) );
170         x = fa[top[x]];
171     }
172     if ( depth[x] > depth[y] ) swap( x, y );
173     ans = max( ans, query_max( 1, dfn[x], dfn[y] ) );
174     return ans;
175 }
176 
177 int tree_query_sum( int x, int y )
178 {
179     int ans = 0;
180     while ( top[x] != top[y] )
181     {
182         if ( depth[top[x]] < depth[top[y]] )
183         {
184             swap( x, y );
185         }
186         ans += query_sum( 1, dfn[top[x]], dfn[x] );
187         x = fa[top[x]];
188     }
189     if ( depth[x] > depth[y] ) swap( x, y );
190     ans += query_sum( 1, dfn[x], dfn[y] );
191     return ans;
192 }
193 
194 int main ()
195 {
196     while ( scanf("%d", &n) != EOF )
197     {
198         init();
199         for ( int i = 1; i < n; i++ )
200         {
201             int u, v;
202             scanf("%d%d", &u, &v);
203             addEdge( u, v );
204             addEdge( v, u );
205         }
206         for ( int i = 1; i <= n; i++ )
207         {
208             scanf("%d", c + i);
209         }
210         dfs1( 1, -1, 1 );
211         dfs2( 1, 1 );
212         build( 1, 1, n );
213         char op[11];
214         int m, x, y;
215         scanf("%d", &m);
216         while ( m-- )
217         {
218             scanf("%s%d%d", op, &x, &y);
219             if ( op[1] == 'M' )
220             {
221                 printf("%d\n", tree_query_max( x, y ));
222             }
223             else if ( op[1] == 'S' )
224             {
225                 printf("%d\n", tree_query_sum( x, y ));
226             }
227             else
228             {
229                 update( 1, dfn[x], y );
230             }
231         }
232     }
233     return 0;
234 }

 

posted @ 2015-08-19 16:55  hxy_has_been_used  阅读(176)  评论(0编辑  收藏  举报