码迷,mamicode.com
首页 > 编程语言 > 详细

求和 --dfs序+树状数组

时间:2020-10-05 21:24:06      阅读:36      评论:0      收藏:0      [点我收藏+]

标签:依次   one   span   bit   https   void   const   sum   hide   

题意:技术图片

 

链接:https://ac.nowcoder.com/acm/contest/5158/I

思路:树状数组主要针对的是区间(而且是一条线段的)求和问题,所以需要利用dfs序和数组 in [ ], out [ ] (前缀和原理),利用dfs进行搜索,每个点依次被访问的顺序就是每个点的dfs序,out [ i ] - in [ i ] 即为子树 i 的区间,

这样就将一棵树记录到了树状数组上。

代码:

链式前向星+dfs序+树状数组

技术图片
 1 #include<stdio.h>
 2 #include<algorithm>
 3 #include<string.h>
 4 #include<string>
 5 #include<iostream>
 6 using namespace std;
 7 typedef long long ll;
 8 #define lowbit(x) (x&(-x))
 9 const int M=1000010;
10 struct node{
11     int to,nxt;
12 };
13 node edge[M*2];
14 int a[M],cnt,tag,n,head[M],in[M],out[M];
15 ll tree[M];
16 void init(){
17      memset(tree,0,sizeof(tree));
18      for(int i=1;i<2*M;i++)
19         edge[i].nxt=-1;
20      for(int i=1;i<M;i++)
21         head[i]=-1;
22      cnt=0;
23 }
24 void add(int v,int u){
25      cnt++;
26      edge[cnt].to=v;
27      edge[cnt].nxt=head[u];
28      head[u]=cnt;
29 }
30 void add1(int x,int d){
31      while(x<=n){
32         tree[x]+=d;
33         x+=lowbit(x);
34      }
35 }
36 ll sum(int x){
37      ll ans=0;
38      while(x){
39         ans+=tree[x];
40         x-=lowbit(x);
41      }
42      return ans;
43 }
44 void dfs(int x,int fa){
45       in[x]=++tag;
46       add1(tag,a[x]);
47       for(int i=head[x];i!=-1;i=edge[i].nxt){
48         int tem=edge[i].to;
49         if(tem!=fa)dfs(tem,x);
50       }
51       out[x]=tag;
52 }
53 int main(){
54      int m,k,u,v,p;
55      while(~scanf("%d%d%d",&n,&m,&k)){
56         tag=0;
57         init();
58         for(int i=1;i<=n;i++)scanf("%d",&a[i]);
59         for(int i=1;i<n;i++){
60             scanf("%d%d",&u,&v);
61             add(u,v);
62             add(v,u);
63         }
64         dfs(k,0);
65         for(int i=1;i<=m;i++){
66             scanf("%d",&p);
67             if(p==1){
68                 scanf("%d%d",&u,&v);
69                 add1(in[u],v);
70             }
71             else{
72                 scanf("%d",&v);
73                 printf("%lld\n",sum(out[v])-sum(in[v]-1));
74             }
75         }
76      }
77      return 0;
78 }
View Code

 

求和 --dfs序+树状数组

标签:依次   one   span   bit   https   void   const   sum   hide   

原文地址:https://www.cnblogs.com/AndreaHtj/p/13761731.html

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