码迷,mamicode.com
首页 > 其他好文 > 详细

hdu5401 Persistent Link/cut Tree

时间:2015-09-11 20:42:09      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:

记忆化递归搜索,注意树的规模可能会很大(2m),用64位整数也需要边计算边取模以防止溢出。

 

http://acm.hdu.edu.cn/showproblem.php?pid=5401

 

技术分享
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <map>
 5 
 6 using namespace std;
 7 typedef __int64 LL;
 8 
 9 const LL M = 1e9 + 7;
10 const int maxn = 100;
11 int m;
12 LL a, b, c, d, l;
13 LL L[maxn], R[maxn];
14 LL f[maxn], L1[maxn];
15 LL g[maxn];
16 int A[maxn], B[maxn];
17 LL ms[maxn];
18 
19 map<LL, LL> map1[maxn];
20 map<pair<LL, LL>, LL> map2[maxn];
21 
22 LL dis(LL tr, LL x, LL y){
23     if(!tr || x == y) return 0;
24     if(x > y) swap(x, y);
25     if(map2[tr].count(make_pair(x, y))) return map2[tr][make_pair(x, y)];
26     if(y < g[A[tr]]) return map2[tr][make_pair(x, y)] = dis(A[tr], x, y);
27     if(x >= g[A[tr]]) return map2[tr][make_pair(x, y)] = dis(B[tr], x - g[A[tr]], y - g[A[tr]]);
28     return map2[tr][make_pair(x, y)] = (dis(A[tr], x, L[tr]) + dis(B[tr], y - g[A[tr]], R[tr]) + L1[tr]) % M;
29 }
30 
31 LL get(LL x, LL tr){
32     if(!tr) return 0;
33     if(map1[tr].count(x)) return map1[tr][x];
34     if(x < g[A[tr]])
35         return map1[tr][x] =
36             (get(x, A[tr]) + get(R[tr], B[tr]) + ms[B[tr]] * (L1[tr] + dis(A[tr], L[tr], x))) % M;
37     return map1[tr][x] =
38         (get(x - g[A[tr]], B[tr]) + get(L[tr], A[tr]) + ms[A[tr]] * (L1[tr] + dis(B[tr], R[tr], x - g[A[tr]]))) % M;
39 }
40 
41 void update(int u){
42     L1[u] = l;
43     L[u] = c, R[u] = d;
44     A[u] = a, B[u] = b;
45     g[u] = g[a] + g[b];
46     ms[u] = g[u] % M;
47     LL ans = 0;
48     ans += (ms[a] * ms[b]) % M * l + f[a] + f[b];
49     ans %= M;
50     LL lhs = get(c, a);
51     LL rhs = get(d, b);
52     ans += (ms[a] * rhs + ms[b] * lhs) % M;
53     ans %= M;
54     printf("%I64d\n", ans);
55     f[u] = ans;
56 }
57 
58 int main(){
59    // freopen("in.txt", "r", stdin);
60     while(~scanf("%d", &m)){
61         for(int i = 0; i <= m; i++) map1[i].clear();
62         for(int i = 0; i <= m; i++) map2[i].clear();
63         ms[0] = g[0] = 1;
64         f[0] = 0;
65         for(int i = 1; i <= m; i++) scanf("%I64d%I64d%I64d%I64d%I64d", &a, &b, &c, &d, &l), update(i);
66     }
67     return 0;
68 }
View Code

 

hdu5401 Persistent Link/cut Tree

标签:

原文地址:http://www.cnblogs.com/astoninfer/p/4802015.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!