[Luogu 3178] HAOI2013 树上操作

<题目链接>


一道比模板还简单的难以置信的裸HLD省选题。

大约是需要long long。

#include <cstdio>
#include <cstring>
const int MAXN=100010,MAXM=200010;
int n,m;
class HLD
{
public:
HLD(void)
{
num=cnt=0;
memset(vis,0,sizeof vis);
memset(head,0,sizeof head);
memset(p,0,sizeof p);
}
void Init(void)
{
for(int i=1;i<=n;++i)
scanf("%lld",&p[i].v);
for(int i=1,u,v;i<n;++i)
{
scanf("%d %d",&u,&v);
AddEdges(u,v);
}
DFS1(1,1),DFS2(1,1),T.Build(this,1,1,n);
}
void AddNode(int x,long long k)
{
T.Update(p[x].DFN,k);
}
void AddSubtree(int x,long long k)
{
T.Add(1,p[x].DFN,p[x].DFN+p[x].size-1,k);
}
long long SumPath(int x)
{
int a;
long long ans=0LL;
while(x)
ans+=T.Sum(1,p[a=p[x].top].DFN,p[x].DFN),x=p[a].ft;
return ans;
}
private:
bool vis[MAXN];
int num,cnt,head[MAXN],rank[MAXN];
struct node
{
int d,ft,son,top,size,DFN;
long long v;
}p[MAXN];
struct edge
{
int nxt,to;
edge(int _nxt=0,int _to=0)
{
nxt=_nxt,to=_to;
}
}e[MAXM];
class SegmentTree
{
public:
void Build(HLD *qwq,int i,int l,int r)
{
s[i]=node(l,r,0LL);
if(l==r)
{
f[l]=i,s[i].v=qwq->p[qwq->rank[l]].v;
return;
}
int j=i<<1,mid=l+r>>1;
Build(qwq,j,l,mid),Build(qwq,j|1,mid+1,r);
PushUp(i);
}
void Update(int i,long long v)
{
i=f[i];
while(i)
s[i].v+=v,i>>=1;
}
void Add(int i,int l,int r,long long v)
{
if(l==s[i].l && r==s[i].r)
{
Modify(i,v);
return;
}
if(s[i].l^s[i].r && s[i].lazy)
PushDown(i);
int j=i<<1,mid=s[i].l+s[i].r>>1;
if(r<=mid)
Add(j,l,r,v);
else if(l>mid)
Add(j|1,l,r,v);
else
Add(j,l,mid,v),Add(j|1,mid+1,r,v);
PushUp(i);
}
long long Sum(int i,int l,int r)
{
if(l==s[i].l && r==s[i].r)
return s[i].v;
if(s[i].l^s[i].r && s[i].lazy)
PushDown(i);
int j=i<<1,mid=s[i].l+s[i].r>>1;
if(r<=mid)
return Sum(j,l,r);
else if(l>mid)
return Sum(j|1,l,r);
else
return Sum(j,l,mid)+Sum(j|1,mid+1,r);
}
private:
int f[MAXN];
struct node
{
int l,r;
long long v,lazy;
node(int _l=0,int _r=0,long long _lazy=0LL)
{
l=_l,r=_r,lazy=_lazy;
}
}s[MAXN<<2];
void Modify(int i,long long v)
{
s[i].v+=v*(long long)(s[i].r-s[i].l+1);
s[i].lazy+=v;
}
void PushUp(int i)
{
int j=i<<1;
s[i].v=s[j].v+s[j|1].v;
}
void PushDown(int i)
{
int j=i<<1;
Modify(j,s[i].lazy),Modify(j|1,s[i].lazy);
s[i].lazy=0LL;
}
}T;
void AddEdge(int u,int v)
{
e[++cnt]=edge(head[u],v);
head[u]=cnt;
}
void AddEdges(int u,int v)
{
AddEdge(u,v),AddEdge(v,u);
}
void DFS1(int u,int k)
{
p[u].d=k,p[u].size=1;
for(int i=head[u],v;i;i=e[i].nxt)
if(!p[v=e[i].to].size)
{
DFS1(v,k+1);
p[v].ft=u,p[u].size+=p[v].size;
if(p[v].size>p[p[u].son].size)
p[u].son=v;
}
}
void DFS2(int u,int top)
{
vis[u]=p[u].top=top,p[u].DFN=++num,rank[num]=u;
if(p[u].son)
DFS2(p[u].son,top);
for(int i=head[u],v;i;i=e[i].nxt)
if(!vis[v=e[i].to])
DFS2(v,v);
}
}HLT;
int main(int argc,char *argv[])
{
scanf("%d %d",&n,&m);
HLT.Init(); for(int i=1,opt,x;i<=m;++i)
{
long long k;
scanf("%d %d",&opt,&x);
switch(opt)
{
case 1:
scanf("%lld",&k);
HLT.AddNode(x,k);
break;
case 2:
scanf("%lld",&k);
HLT.AddSubtree(x,k);
break;
case 3:
printf("%lld\n",HLT.SumPath(x));
break;
}
}
return 0;
}

谢谢阅读。

[Luogu 3178] HAOI2013 树上操作的更多相关文章

  1. 【luogu P3178 [HAOI2015]树上操作】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3178 模板题 菜 #include <cstdio> #include <cstring& ...

  2. 洛谷 3178 [HAOI2015]树上操作

    [题解] 就是个树链剖分的模板题. #include<cstdio> #include<algorithm> #include<cstring> #define L ...

  3. LUOGU P3178 [HAOI2015]树上操作

    传送门 解题思路 树链剖分裸题,线段树维护. 代码 #include<iostream> #include<cstdio> #include<cstring> #d ...

  4. 洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)

    P3178 [HAOI2015]树上操作 题目链接:https://www.luogu.org/problemnew/show/P3178 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边 ...

  5. [HAOI2015]树上操作(树链剖分)

    [HAOI2015]树上操作(luogu) Description 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种: 操作 1 :把某个节点 x 的点权增 ...

  6. 【BZOJ4034】[HAOI2015]树上操作 树链剖分+线段树

    [BZOJ4034][HAOI2015]树上操作 Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 ...

  7. HAOI2015 树上操作

    HAOI2015 树上操作 题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根 ...

  8. bzoj千题计划242:bzoj4034: [HAOI2015]树上操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=4034 dfs序,树链剖分 #include<cstdio> #include<io ...

  9. bzoj4034[HAOI2015]树上操作 树链剖分+线段树

    4034: [HAOI2015]树上操作 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 6163  Solved: 2025[Submit][Stat ...

随机推荐

  1. 【转载】java byte转十六进制

    public static String bytes2HexString(byte[] b) { String ret = ""; for (int i = 0; i < b ...

  2. Javascript闭包演示【转】

    文章出自http://www.cnblogs.com/snandy/archive/2011/03/01/1967628.html 有个网友问了个问题,如下的html,为什么点击所有的段落p输出都是5 ...

  3. 关于set和get机制的整理

    首先这是es5新增的:定义是设置和获取对象属性时候出发的方法,属于修饰器: 犀牛书例子: function test(n){ return { get count(){ return n }, set ...

  4. NSValue的valueWithBytes:objCType:方法

    + (NSValue *)valueWithBytes:(const void *)value objCType:(const char *)type; NSValue的valueWithBytes: ...

  5. 20145214 《Java程序设计》第7周学习总结

    20145214 <Java程序设计>第7周学习总结 教材学习内容总结 时间的度量 格林威治标准时间(GMT),现已不作为标准时间使用,即使标注为GMT(格林威治时间),实际上谈到的的是U ...

  6. [zt]手把手教你写对拍程序(PASCAL)

    谁适合看这篇文章? ACMERS,OIERS或其它参加算法竞赛或需要算法的人 对操作系统并不太熟悉的人 不会写对拍的人 在网上找不到一个特别详细的对拍样例的人 不嫌弃我写的太低幼的人 前言 在NOIP ...

  7. iOS- xib(nib) 的重用(在有些情况下有利于加快项目功能的实现)

    0.前言 在项目开发中,我们经常会碰到,某些视图View 内部基本空间都一样,只是数据不同,这时,我们可以用xib来将这个视图封装起来多次重用, (例如,大小固定 控件固定的TableViewCell ...

  8. Scala快速入门-基本数据结构

    模式匹配 使用用模式匹配实现斐波那契 def fibonacci(in: Any): Int = in match { case 0 => 0 case 1 => 1 case n: In ...

  9. == 和equal的区别?-005

    1,== 和equal的区别? ==比较两个值是否相等,equal比较对对象的引用是否一致 举例: int a = 2; int b = 2; System.err.println(a == b);/ ...

  10. 【转】关于增量链接(incremental linking)

    增量链接(Incremental Linking)这个词语在使用Visual C++时经常会遇到(其实不只是VS系列,其它链接器也有这个特性), 就比如经常遇到的:上一个增量链接没有生成它, 正在执行 ...