• Codeforces 739B Alyona and a tree (树上路径倍增及差分)


    题目链接 Alyona and a tree

    弄了好几个小时终于Accepted了,之后发现这个题是Div1的。

    比较考验我思维的一道好题。

    首先,做一遍DFS预处理出t[i][j]和d[i][j]。t[i][j]表示从第i个节点到离他第2^j近的祖先,d[i][j]表示从i开始到t[i][j]的路径上的路径权值总和。

    在第一次DFS的同时,对节点x进行定位(结果为dist(x, y)<=a(y))的离x最远的x的某个祖先,然后进行O(1)的差分。

    第一次DFS完成后,做第二次DFS统计答案(统计差分后的结果)。时间复杂度为O(NlgN)

    代码送上。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 #define REP(i,n)                for(int i(0); i <  (n); ++i)
     6 #define rep(i,a,b)              for(int i(a); i <= (b); ++i)
     7 #define dec(i,a,b)              for(int i(a); i >= (b); --i)
     8 #define for_edge(i,x)           for(int i = H[x]; i; i = X[i])
     9 
    10 #define LL      long long
    11 #define ULL     unsigned long long
    12 #define MP      make_pair
    13 #define PB      push_back
    14 #define FI      first
    15 #define SE      second
    16 #define INF     1 << 30
    17 #define sz(x)    (int)x.size()
    18 
    19 const int N     =    200000      +       10;
    20 const int M     =    10000       +       10;
    21 const int Q     =    1000        +       10;
    22 const int A     =    30          +       1;
    23 
    24 
    25 vector <int> v[N], c[N];
    26 LL a[N], deep[N];
    27 LL x, y;
    28 int n, cnt;
    29 LL t[N][A], d[N][A];
    30 LL g[N], value[N];
    31 LL s[N];
    32 LL ans[N];
    33 
    34 void dfs(int x, int fa){
    35     if (g[x]){
    36         t[x][0] = g[x];
    37         d[x][0] = value[x];
    38         for (int i = 0; t[t[x][i]][i]; ++i){
    39             t[x][i + 1] = t[t[x][i]][i];
    40             d[x][i + 1] = d[t[x][i]][i] + d[x][i];
    41         }
    42         int now = x, noww = 0;
    43         bool flag = false;
    44         dec(i, 20, 0){
    45             if (t[now][i] && d[now][i] + noww <= a[x]){
    46                 noww += d[now][i];
    47                 now = t[now][i];
    48                 flag = true;
    49             }
    50         }
    51         if (flag){
    52             --s[g[now]]; ++s[g[x]];
    53         }
    54     }
    55 
    56     REP(i, sz(v[x])){
    57         int u = v[x][i];
    58         deep[u] = deep[x] + 1;
    59         dfs(u, x);
    60     }
    61 }
    62 
    63 void dfs2(int x){
    64     ans[x] += s[x];
    65     REP(i, sz(v[x])){
    66         dfs2(v[x][i]);
    67         ans[x] += ans[v[x][i]];
    68     }
    69 }
    70 
    71 int main(){
    72 
    73     scanf("%d", &n);
    74     rep(i, 1, n) scanf("%lld", a + i);
    75     rep(i, 2, n){
    76         scanf("%lld%lld", &x, &y); g[i] = x; value[i] = y;
    77         v[x].PB(i), c[x].PB(y);
    78     }
    79 
    80     memset(s, 0, sizeof s);
    81     cnt = 0;
    82     deep[1] = 0;
    83     dfs(1, 0);
    84     memset(ans, 0, sizeof ans);
    85     dfs2(1);
    86     rep(i, 1, n - 1) printf("%lld ", ans[i]);
    87     printf("%lld
    ", ans[n]);
    88 
    89     return 0;
    90 
    91 }
  • 相关阅读:
    .NET简谈插件系统开发模式
    .NET实现之(自动更新)
    .NET简谈互操作(二:先睹为快)
    .NET实现之(WebBrowser数据采集—基础篇)
    .NET简谈设计模式之(观察者模式)
    .NET简谈平台大局观
    .NET实现之(简易ORM)
    .NET简谈面向接口编程
    .NET简谈事件与委托
    .NET实现之(WebBrowser数据采集—终结篇)
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/6352240.html
Copyright © 2020-2023  润新知