codechef FUN WITH TREES

题目大意:

       给一棵树root=1的树:

      给一些操作:u  v 的路径所有节点的node + val;

      最后m个询问:u 节点(包括u) sum%mod 是多少。

  LCA + RMQ;

 我们每次mark ,u , v, +=val;

fa=lca[u,v])-=val;

fa[fa]-=val

你会发现下次DFS一边的时候可以把所以答案更新出来。DFS 从下往上更新。

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <vector>
  6 #include <queue>
  7 #include <set>
  8 #include <map>
  9 #include <string>
 10 #include <math.h>
 11 #include <stdlib.h>
 12 #include <time.h>
 13 using namespace std;
 14 #define N 100001
 15 #define LN 20
 16 #define mod 1000000007
 17 
 18 vector<int>mp[N];
 19 int mark[N];
 20 int dp[LN][N];
 21 int dep[N];
 22 int ans[N],tmp[N];
 23 
 24 int lca(int l,int r)
 25 {
 26   if (dep[l]<dep[r]) swap(l,r);
 27   int dif=dep[l]-dep[r];
 28   for (int i=0;i<LN;i++)
 29   if ((dif>>i)&1) l=dp[i][l];
 30 
 31   if (l==r)  return l;
 32   
 33   for (int i=LN-1;i>=0;i--)
 34   if (dp[i][l]!=dp[i][r]) l=dp[i][l],r=dp[i][r];
 35   return dp[0][l];
 36 }
 37 
 38 void dfs(int u,int fa,int level)
 39 {
 40    dp[0][u]=fa;
 41    dep[u]=level;
 42    for (int i=0;i<mp[u].size();i++)
 43    {
 44      int  v=mp[u][i];
 45      if (v==fa) continue;
 46      dfs(v,u,level+1);
 47    }
 48 }
 49 
 50 int dfs2(int u,int fa=0)
 51 {
 52   int sum=mark[u];
 53   for (int i=0;i<mp[u].size();i++)
 54   {
 55     int v=mp[u][i];
 56     if (v==fa) continue;
 57     dfs2(v,u);
 58     sum+=tmp[v];
 59     sum%=mod;
 60     ans[u]+=ans[v];
 61     ans[u]%=mod;
 62   }
 63   tmp[u]=sum;
 64   ans[u]+=tmp[u];
 65   ans[u]%=mod;
 66 }
 67 
 68 int main()
 69 {
 70    int n,u,q;
 71    scanf("%d",&n);
 72    scanf("%d%d",&u,&q);
 73   // for (int i=0;i<=n;i++) mp[i].clear();
 74    for (int i=1;i<n;i++)
 75    {
 76      int a,b;
 77      scanf("%d%d",&a,&b);
 78      mp[a].push_back(b);
 79      mp[b].push_back(a);
 80    }
 81    dfs(1,0,0);
 82    for (int j=1;j<LN;j++)
 83    for (int i=1;i<=n;i++)
 84    dp[j][i]=dp[j-1][dp[j-1][i]];
 85    while (u--)
 86    {
 87        int a,b,c;
 88        scanf("%d%d%d",&a,&b,&c);
 89        mark[a]+=c;
 90        mark[b]+=c;
 91        mark[a]%=mod;
 92        mark[b]%=mod;
 93        int l=lca(a,b);
 94        mark[l]-=c;
 95        mark[l]%=mod;
 96        mark[dp[0][l]]-=c;
 97        mark[dp[0][l]]%=mod;
 98    }
 99 
100    dfs2(1);
101    while (q--)
102    {
103      int x;
104      scanf("%d",&x);
105      printf("%d
",(ans[x]+mod)%mod);
106    }
107 
108    return 0;
109 }
View Code
原文地址:https://www.cnblogs.com/forgot93/p/4364163.html