您的位置:首页 > 其它

hdu5401 Persistent Link/cut Tree

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

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

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>

using namespace std;
typedef __int64 LL;

const LL M = 1e9 + 7;
const int maxn = 100;
int m;
LL a, b, c, d, l;
LL L[maxn], R[maxn];
LL f[maxn], L1[maxn];
LL g[maxn];
int A[maxn], B[maxn];
LL ms[maxn];

map<LL, LL> map1[maxn];
map<pair<LL, LL>, LL> map2[maxn];

LL dis(LL tr, LL x, LL y){
if(!tr || x == y) return 0;
if(x > y) swap(x, y);
if(map2.count(make_pair(x, y))) return map2[make_pair(x, y)];
if(y < g[A]) return map2[make_pair(x, y)] = dis(A, x, y);
if(x >= g[A]) return map2[make_pair(x, y)] = dis(B, x - g[A], y - g[A]);
return map2[make_pair(x, y)] = (dis(A, x, L) + dis(B, y - g[A], R) + L1) % M;
}

LL get(LL x, LL tr){
if(!tr) return 0;
if(map1.count(x)) return map1[x];
if(x < g[A])
return map1[x] =
(get(x, A) + get(R, B) + ms[B] * (L1+ dis(A, L, x))) % M;
return map1[x] =
(get(x - g[A], B) + get(L, A) + ms[A] * (L1+ dis(B, R, x - g[A]))) % M;
}

void update(int u){
L1[u] = l;
L[u] = c, R[u] = d;
A[u] = a, B[u] = b;
g[u] = g[a] + g[b];
ms[u] = g[u] % M;
LL ans = 0;
ans += (ms[a] * ms[b]) % M * l + f[a] + f[b];
ans %= M;
LL lhs = get(c, a);
LL rhs = get(d, b);
ans += (ms[a] * rhs + ms[b] * lhs) % M;
ans %= M;
printf("%I64d\n", ans);
f[u] = ans;
}

int main(){
// freopen("in.txt", "r", stdin);
while(~scanf("%d", &m)){
for(int i = 0; i <= m; i++) map1[i].clear();
for(int i = 0; i <= m; i++) map2[i].clear();
ms[0] = g[0] = 1;
f[0] = 0;
for(int i = 1; i <= m; i++) scanf("%I64d%I64d%I64d%I64d%I64d", &a, &b, &c, &d, &l), update(i);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: