地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=3966
题目:
Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 11512    Accepted Submission(s): 3028
思路: 树链修改,单点查询。
方法有以下两种
1.树链剖分
模板题,不解释;
2.dfs+树状数组
具体见我另外一篇文章的树链修改,单点查询问题。http://www.cnblogs.com/weeping/p/6847112.html
 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 #define MP make_pair
 6 #define PB push_back
 7 typedef long long LL;
 8 typedef pair<int,int> PII;
 9 const double eps=1e-8;
10 const double pi=acos(-1.0);
11 const int K=5e4+7;
12 const int mod=1e9+7;
13 
14 vector<int>mp[K];
15 int top[K],sz[K],fa[K],son[K],id[K],hid[K],deep[K];
16 int cnt,add[4*K],a[K];
17 
18 int query(int o,int l,int r,int x)
19 {
20     if(l==r)    return add[o];
21     int mid=l+r>>1;
22     if(x<=mid) return query(o<<1,l,mid,x)+add[o];
23     return query(o<<1|1,mid+1,r,x)+add[o];
24 }
25 int update(int o,int l,int r,int nl,int nr,int v)
26 {
27     if(l==nl&&r==nr)
28        return add[o]+=v;
29     int mid=l+r>>1;
30     if(nr<=mid) update(o<<1,l,mid,nl,nr,v);
31     else if(nl>mid) update(o<<1|1,mid+1,r,nl,nr,v);
32     else update(o<<1,l,mid,nl,mid,v),update(o<<1|1,mid+1,r,mid+1,nr,v);
33 }
34 void dfs1(int x,int f)
35 {
36     sz[x]=1,fa[x]=f,son[x]=-1,deep[x]=deep[f]+1;
37     for(int i=0;i<mp[x].size();i++)
38     if(mp[x][i]!=f)
39     {
40         dfs1(mp[x][i],x);
41         sz[x]+=sz[mp[x][i]];
42         if(son[x]==-1||sz[son[x]]<sz[mp[x][i]])
43             son[x]=mp[x][i];
44     }
45 }
46 void dfs2(int x,int f)  ///每条边用深度低的节点的序号表示
47 {
48     top[x]=f,id[x]=++cnt,hid[id[x]]=x;
49     if(son[x]!=-1) dfs2(son[x],f);
50     for(int i=0;i<mp[x].size();i++)
51     if(mp[x][i]!=fa[x]&&mp[x][i]!=son[x])
52         dfs2(mp[x][i],mp[x][i]);
53 }
54 void tree_update(int x,int y,int v)
55 {
56     while(top[x]!=top[y])
57     {
58         if(deep[top[x]]<deep[top[y]]) swap(x,y);
59         update(1,1,cnt,id[top[x]],id[x],v);//更新x-top[x]-fa[top[x]]
60         x=fa[top[x]];//所以直接fa[top[x]]
61     }
62     //if(x==y) return;
63     if(deep[x]>deep[y]) swap(x,y);
64     update(1,1,cnt,id[x],id[y],v);///注意id[son[x]]
65 }
66 int tree_query(int x)
67 {
68     return query(1,1,cnt,id[x])+a[x];
69 }
70 int main(void)
71 {
72     //freopen("in.acm","r",stdin);
73     int n,m,q;
74     while(~scanf("%d%d%d",&n,&m,&q))
75     {
76         cnt=0;
77         memset(add,0,sizeof add);
78         for(int i=1;i<=n;i++)
79             scanf("%d",a+i),mp[i].clear();
80         for(int i=1,x,y;i<n;i++)
81             scanf("%d%d",&x,&y),mp[x].PB(y),mp[y].PB(x);
82         dfs1(1,0),dfs2(1,1);
83         int x,y,v;
84         char op[10];
85         while(q--)
86         {
87             scanf("%s%d",op,&x);
88             if(op[0]==‘Q‘)
89                 printf("%d\n",tree_query(x));
90             else
91             {
92                 scanf("%d%d",&y,&v);
93                 if(op[0]==‘D‘)v=-v;
94                 tree_update(x,y,v);
95             }
96         }
97     }
98     return 0;
99 }
原文:http://www.cnblogs.com/weeping/p/6869809.html