LOJ2125
LOJ2125 树上操作
题目描述
有一棵点数为 N 的树,以点 1 为根,且树有点权。然后有 M 个操作,分为三种:
- 把某个节点 x 的点权增加 aa 。
- 把某个节点 x 为根的子树中所有点的点权都增加 a 。
- 询问某个节点 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
数据范围与提示
对于 100% 的数据, N,M≤10^5 ,且所有输入数据的绝对值都不会超过 10^6 。
________________________________________________________________________________________
简单的树链剖分,而且树上的查询也比较简单,只是从某个节点到根的权值和。需要注意的如何处理子树的权值修改。这个就是用到了DFS序。需要记录每个点为跟的子树在线段树中左右边界。
________________________________________________________________________________________
1 #include<bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const ll maxn=1e5+10;
5 ll n,m;
6 ll w[maxn];
7 struct edge
8 {
9 int u,v,nxt;
10 }e[maxn<<1];
11 ll head[maxn],js;
12 void addage(ll u,ll v)
13 {
14 e[++js].u=u;e[js].v=v;
15 e[js].nxt=head[u];head[u]=js;
16 }
17 ll dep[maxn],siz[maxn],fat[maxn],son[maxn];
18 void dfs(int u,int fa)
19 {
20 siz[u]=1;
21 dep[u]=dep[fa]+1;
22 fat[u]=fa;
23 for(ll i=head[u];i;i=e[i].nxt)
24 {
25 ll v=e[i].v;
26 if(v==fa)continue;
27 dfs(v,u);
28 siz[u]+=siz[v];
29 if(!son[u] || siz[son[u]]<siz[v])son[u]=v;
30 }
31 }
32 ll lp[maxn],rp[maxn],top[maxn],fos[maxn],p;
33 void getpos(ll u,ll fa)
34 {
35 lp[u]=++p;
36 fos[p]=u;
37 top[u]=fa;
38 if(!son[u])
39 {
40 rp[u]=p;
41 return;
42 }
43 getpos(son[u],fa);
44 for(ll i=head[u];i;i=e[i].nxt)
45 {
46 ll v=e[i].v;
47 if(v!=fat[u] && v!=son[u])getpos(v,v);
48 }
49 rp[u]=p;
50 }
51 ll sum[maxn<<2],delt[maxn<<2];
52 inline void updat(ll cur)
53 {
54 sum[cur]=sum[cur<<1]+sum[cur<<1|1];
55 }
56 void build(ll cur,ll l,ll r)
57 {
58 if(l==r)
59 {
60 sum[cur]=w[fos[l]];
61 return;
62 }
63 ll mid=(l+r)>>1;
64 build(cur<<1,l,mid);
65 build(cur<<1|1,mid+1,r);
66 updat(cur);
67 }
68 void down(ll cur,ll l,ll r)
69 {
70 ll mid=(l+r)>>1;
71 delt[cur<<1]+=delt[cur];
72 delt[cur<<1|1]+=delt[cur];
73 sum[cur<<1]+=delt[cur]*(mid-l+1);
74 sum[cur<<1|1]+=delt[cur]*(r-mid);
75 delt[cur]=0;
76 }
77 void add(ll cur,ll l,ll r,ll p,ll x)
78 {
79 if(l==r)
80 {
81 sum[cur]+=x;
82 return ;
83 }
84 ll mid=(l+r)>>1;
85 if(delt[cur])down(cur,l,r);
86 if(p<=mid)add(cur<<1,l,mid,p,x);
87 else add(cur<<1|1,mid+1,r,p,x);
88 updat(cur);
89 }
90 void add_(ll cur,ll l,ll r,ll ql,ll qr,ll x)
91 {
92 if(ql<=l && r<=qr)
93 {
94 sum[cur]+=(r-l+1)*x;
95 delt[cur]+=x;
96 return ;
97 }
98 down(cur,l,r);
99 ll mid=(l+r)>>1;
100 if(ql<=mid)add_(cur<<1,l,mid,ql,qr,x);
101 if(mid<qr)add_(cur<<1|1,mid+1,r,ql,qr,x);
102 updat(cur);
103 }
104 ll query(ll cur,ll l,ll r,ll ql,ll qr)
105 {
106 if(ql<=l && r<=qr)return sum[cur];
107 ll ans=0,mid=(l+r)>>1;
108 if(delt[cur])down(cur,l,r);
109 if(ql<=mid)ans+=query(cur<<1,l,mid,ql,qr);
110 if(mid<qr)ans+=query(cur<<1|1,mid+1,r,ql,qr);
111 return ans;
112 }
113 ll ask(ll x)
114 {
115 ll ans=0;
116 while(x)
117 {
118 ll tpx=top[x];
119 ans+=query(1,1,n,lp[tpx],lp[x]);
120 x=fat[tpx];tpx=top[x];
121 }
122 return ans;
123 }
124 int main()
125 {
126 scanf("%lld%lld",&n,&m);
127 for(int i=1;i<=n;++i)scanf("%lld",w+i);
128 for(ll u,v,i=1;i<n;++i)
129 {
130 scanf("%lld%lld",&u,&v);
131 addage(u,v);addage(v,u);
132 }
133 dfs(1,0);
134 getpos(1,1);
135 build(1,1,n);
136 while(m--)
137 {
138 ll x,a,op;
139 scanf("%lld%lld",&op,&x);
140 if(op!=3)scanf("%lld",&a);
141 if(op==1)add(1,1,n,lp[x],a);
142 else if(op==2)add_(1,1,n,lp[x],rp[x],a);
143 else printf("%lld\n",ask(x));
144 }
145 return 0;
146 }
LOJ2125的更多相关文章
随机推荐
- [leetcode]House Robber1,2
/** * 一. * You are a professional robber planning to rob houses along a street.Each house has a cert ...
- HTML表格样式
一.表格的表头 1 <html> 2 3 <body> 4 5 <h4>表头:</h4> 6 <table border="1" ...
- java nio中,HeapByteBuffer与DirectByteBuffer的区别
HeapByteBuffer,顾名思义,是写在jvm堆上面的一个buffer,底层的本质是一个数组,用类封装维护了很多的索引(limit/position/capacity等) DirectByteB ...
- 鸿蒙HarmonyOS应用开发落地实践,Harmony Go 技术沙龙落地北京
12月26日,华为消费者BG软件部开源中心与51CTO Harmony OS技术社区携手,共同主办了主题为"Harmony OS 应用开发落地实践"的 Harmony Go 技术沙 ...
- 风炫安全Web安全学习第十六节课 高权限sql注入getshell
风炫安全Web安全学习第十六节课 高权限sql注入getshell sql高权限getshell 前提条件: 需要知道目标网站绝对路径 目录具有写的权限 需要当前数据库用户开启了secure_file ...
- Promise入门到精通(初级篇)-附代码详细讲解
Promise入门到精通(初级篇)-附代码详细讲解 Promise,中文翻译为承诺,约定,契约,从字面意思来看,这应该是类似某种协议,规定了什么事件发生的条件和触发方法. Pr ...
- 【MySQL 高级】索引优化分析
MySQL高级 索引优化分析 SQL 的效率问题 出现性能下降,SQL 执行慢,执行时间长,等待时间长等情况,可能的原因有: 查询语句写的不好 索引失效 单值索引:在 user 表中给 name 属性 ...
- spring中的工厂模式
spring的bean的创建原理就是框架利用反射创建出实例对象 工厂模式:工厂帮我们创建对象:有一个专门帮我们创建对象的类,我们把这个类叫做工厂类. 例如:Plane plane = PlaneFac ...
- Python——绘制埃菲尔铁塔
from turtle import * import turtle colormode(255) #设置turtle颜色模式 speed(0) #速度 setup(800,800,720,0) #画 ...
- python学习笔记 | PyCharm创建文件时自动添加头文件
File Settings Editor File and Code Templates Python Script 然后在右边的框中写入信息就可以啦: # -*- coding: utf-8 -*- ...