[HAOI2015]树上操作
【题目描述】
有一棵点数为N的树,以点1为根,且树点有边权。然后有M个操作,分为三种:
操作1:把某个节点x的点权增加a。
操作2:把某个节点x为根的子树中所有点的点权都增加a。
操作3:询问某个节点x到根的路径中所有点的点权和。
【输入格式】
第一行两个整数N,M,表示点数和操作数。
接下来一行N个整数,表示树中节点的初始权值。
接下来N-1行每行两个正整数fr,to,表示该树中存在一条边(fr,to)。
再接下来M行,每行分别表示一次操作。其中第一个数表示该操作的种类(1~3),之后接这个操作的参数(x或者x a)。
【输出格式】
对于每个询问操作,输出该询问的答案。答案之间用换行隔开。
【样例输入】
5 5
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3
【样例输出】
6
9
13
【提示】
对于30%的数据,N,M<=1000
对于50%的数据,N,M<=100000且数据随机。
对于100%的数据,N,M<=100000,且所有输入数据的绝对值都不会超过10^6。
很有思考性的题,所以贴出来。
题解链接:http://www.cnblogs.com/Asm-Definer/p/4466729.html
1操作直接在BIT 操作,
还要读入挂,OI真辛苦
1 #include<stdio.h>
2 #include<algorithm>
3 #include<math.h>
4 #include<vector>
5 #include<string.h>
6 #include<string>
7 #include<set>
8 #include<iostream>
9 using namespace std;
10 typedef long long ll;
11 #define N 153333
12
13 vector<int>mp[N];
14 int a[N],dep[N],st[N],ed[N],tot=1;
15 ll f1[N],f2[N],c[N];
16 int head[N];
17 struct node
18 {
19 int v,next;
20 }e[N<<1];
21 int n,m;
22 int lowbit(int x)
23 {
24 return x&-x;
25 }
26
27 void add1(int x,ll v)
28 {
29 for (int i=x;i<=n;i+=lowbit(i)) f1[i]+=v;
30 }
31 void add2(int x,ll v)
32 {
33 for (int i=x;i<=n;i+=lowbit(i)) f2[i]+=v;
34 }
35 ll query1(int x)
36 {
37 ll s=0;
38 for (int i=x;i>0;i-=lowbit(i))
39 s+=f1[i];
40 return s;
41 }
42 ll query2(int x)
43 {
44 ll s=0;
45 for (int i=x;i>0;i-=lowbit(i))
46 s+=f2[i];
47 return s;
48 }
49
50 void dfs(int u,int pre,int t,ll sum)
51 {
52 st[u]=tot++;
53 dep[u]=t;
54 sum+=a[u];
55 c[u]=sum;
56 for (int i=head[u];i!=-1;i=e[i].next)
57 {
58 int v=e[i].v;
59 if (v==pre) continue;
60 dfs(v,u,t+1,sum);
61 }
62 ed[u]=tot-1;
63 }
64 void judge()
65 {
66 freopen("haoi2015_t2.in","r",stdin);
67 freopen("haoi2015_t2.out","w",stdout);
68
69 }
70 int tt;
71 void add(int u,int v)
72 {
73 e[tt].v=v;
74 e[tt].next=head[u];
75 head[u]=tt++;
76 }
77
78 void Getz(int &x){
79 int ch;
80 while(ch=getchar(),ch<48||ch>57);x=ch-48;
81 while(ch=getchar(),ch>47&&ch<58) x=x*10+ch-48;
82 }
83 int main()
84 {
85 judge();
86 tt=0;
87 memset(head,-1,sizeof(head));
88 //scanf("%d%d",&n,&m);
89 Getz(n);
90 Getz(m);
91 for (int i=1;i<=n;i++) Getz(a[i]);
92 for (int i=1;i<n;i++)
93 {
94 int x,y;
95 // scanf("%d%d",&x,&y);
96 Getz(x); Getz(y);
97 //mp[x].push_back(y);
98 add(x,y);
99 add(y,x);
100 //mp[y].push_back(x);
101 }
102 dfs(1,-1,1,0);
103 // for (int i=1;i<=n;i++)
104 // cout<<st[i]<<" "<<ed[i]<<endl;
105
106 while (m--)
107 {
108 int op,u,v;
109 scanf("%d",&op);
110 if (op==1)
111 {
112 //scanf("%d%d",&u,&v);
113 Getz(u); Getz(v);
114 add2(st[u],v);add2(ed[u]+1,-v);
115 }else if (op==2)
116 {
117 // scanf("%d%d",&u,&v);
118 Getz(u); Getz(v);
119 ll tmp=1-dep[u];
120 tmp*=v;
121 add1(st[u],v),add1(ed[u]+1,-v);
122 add2(st[u],tmp),add2(ed[u]+1,-tmp);
123 }
124 else
125 {
126 //scanf("%d",&u);
127 Getz(u);
128 printf("%lld\n",c[u]+query1(st[u])*dep[u]+query2(st[u]));
129 }
130 }
131
132 return 0;
2 #include<algorithm>
3 #include<math.h>
4 #include<vector>
5 #include<string.h>
6 #include<string>
7 #include<set>
8 #include<iostream>
9 using namespace std;
10 typedef long long ll;
11 #define N 153333
12
13 vector<int>mp[N];
14 int a[N],dep[N],st[N],ed[N],tot=1;
15 ll f1[N],f2[N],c[N];
16 int head[N];
17 struct node
18 {
19 int v,next;
20 }e[N<<1];
21 int n,m;
22 int lowbit(int x)
23 {
24 return x&-x;
25 }
26
27 void add1(int x,ll v)
28 {
29 for (int i=x;i<=n;i+=lowbit(i)) f1[i]+=v;
30 }
31 void add2(int x,ll v)
32 {
33 for (int i=x;i<=n;i+=lowbit(i)) f2[i]+=v;
34 }
35 ll query1(int x)
36 {
37 ll s=0;
38 for (int i=x;i>0;i-=lowbit(i))
39 s+=f1[i];
40 return s;
41 }
42 ll query2(int x)
43 {
44 ll s=0;
45 for (int i=x;i>0;i-=lowbit(i))
46 s+=f2[i];
47 return s;
48 }
49
50 void dfs(int u,int pre,int t,ll sum)
51 {
52 st[u]=tot++;
53 dep[u]=t;
54 sum+=a[u];
55 c[u]=sum;
56 for (int i=head[u];i!=-1;i=e[i].next)
57 {
58 int v=e[i].v;
59 if (v==pre) continue;
60 dfs(v,u,t+1,sum);
61 }
62 ed[u]=tot-1;
63 }
64 void judge()
65 {
66 freopen("haoi2015_t2.in","r",stdin);
67 freopen("haoi2015_t2.out","w",stdout);
68
69 }
70 int tt;
71 void add(int u,int v)
72 {
73 e[tt].v=v;
74 e[tt].next=head[u];
75 head[u]=tt++;
76 }
77
78 void Getz(int &x){
79 int ch;
80 while(ch=getchar(),ch<48||ch>57);x=ch-48;
81 while(ch=getchar(),ch>47&&ch<58) x=x*10+ch-48;
82 }
83 int main()
84 {
85 judge();
86 tt=0;
87 memset(head,-1,sizeof(head));
88 //scanf("%d%d",&n,&m);
89 Getz(n);
90 Getz(m);
91 for (int i=1;i<=n;i++) Getz(a[i]);
92 for (int i=1;i<n;i++)
93 {
94 int x,y;
95 // scanf("%d%d",&x,&y);
96 Getz(x); Getz(y);
97 //mp[x].push_back(y);
98 add(x,y);
99 add(y,x);
100 //mp[y].push_back(x);
101 }
102 dfs(1,-1,1,0);
103 // for (int i=1;i<=n;i++)
104 // cout<<st[i]<<" "<<ed[i]<<endl;
105
106 while (m--)
107 {
108 int op,u,v;
109 scanf("%d",&op);
110 if (op==1)
111 {
112 //scanf("%d%d",&u,&v);
113 Getz(u); Getz(v);
114 add2(st[u],v);add2(ed[u]+1,-v);
115 }else if (op==2)
116 {
117 // scanf("%d%d",&u,&v);
118 Getz(u); Getz(v);
119 ll tmp=1-dep[u];
120 tmp*=v;
121 add1(st[u],v),add1(ed[u]+1,-v);
122 add2(st[u],tmp),add2(ed[u]+1,-tmp);
123 }
124 else
125 {
126 //scanf("%d",&u);
127 Getz(u);
128 printf("%lld\n",c[u]+query1(st[u])*dep[u]+query2(st[u]));
129 }
130 }
131
132 return 0;
133 }
随性Code