zoukankan      html  css  js  c++  java
  • hdu5401 Persistent Link/cut Tree

    记忆化递归搜索,注意树的规模可能会很大(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
    ", 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
  • 相关阅读:
    解题报告 百进制数
    解题报告 Loongint 的夜晚
    解题报告 树形图计数
    解题报告 一元三次方程求解
    解题报告 Loongint 的旅行安排
    解题报告 数字查找
    用C++编写简单绘图语言的词法分析器——程序清单
    C++ 连接 mysql 的一个例子(Visual Studio 2005)
    fedora 8 下JDK 6.0 配置
    IBM DB2 V9 常用命令
  • 原文地址:https://www.cnblogs.com/astoninfer/p/4802015.html
Copyright © 2011-2022 走看看