【题目链接】

点击打开链接

【算法】

树链剖分

子树的DFS序是连续的一段!

【代码】

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010 struct Edge
{
int to,nxt;
} e[MAXN*]; int i,opt,n,m,q,x,y,val,tot,timer;
int dfn[MAXN],pos[MAXN],head[MAXN],size[MAXN],
son[MAXN],top[MAXN],fa[MAXN],dep[MAXN];
long long a[MAXN]; template <typename T> inline void read(T &x)
{
long long f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
template <typename T> inline void write(T x)
{
if (x < )
{
putchar('-');
x = -x;
}
if (x > ) write(x/);
putchar(x%+'');
}
template <typename T> inline void writeln(T x)
{
write(x);
puts("");
} struct SegmentTree
{
struct Node
{
int l,r;
long long sum,tag;
} Tree[MAXN*];
inline void update(int index)
{
Tree[index].sum = Tree[index<<].sum + Tree[index<<|].sum;
}
inline void pushdown(int index)
{
int l = Tree[index].l,r = Tree[index].r;
int mid = (l + r) >> ;
if (Tree[index].tag)
{
Tree[index<<].sum += Tree[index].tag * (mid - l + );
Tree[index<<|].sum += Tree[index].tag * (r - mid);
Tree[index<<].tag += Tree[index].tag;
Tree[index<<|].tag += Tree[index].tag;
Tree[index].tag = ;
}
}
inline void build(int index,int l,int r)
{
int mid;
Tree[index].l = l;
Tree[index].r = r;
if (l == r)
{
Tree[index].sum = a[pos[l]];
return;
}
mid = (l + r) >> ;
build(index<<,l,mid);
build(index<<|,mid+,r);
update(index);
}
inline void add1(int index,int pos,long long val)
{
int mid;
if (Tree[index].l == Tree[index].r)
{
Tree[index].sum += val;
return;
}
pushdown(index);
mid = (Tree[index].l + Tree[index].r) >> ;
if (mid >= pos) add1(index<<,pos,val);
else add1(index<<|,pos,val);
update(index);
}
inline void add2(int index,int l,int r,long long val)
{
int mid;
if (Tree[index].l == l && Tree[index].r == r)
{
Tree[index].sum += val * (r - l + );
Tree[index].tag += val;
return;
}
pushdown(index);
mid = (Tree[index].l + Tree[index].r) >> ;
if (mid >= r) add2(index<<,l,r,val);
else if (mid + <= l) add2(index<<|,l,r,val);
else
{
add2(index<<,l,mid,val);
add2(index<<|,mid+,r,val);
}
update(index);
}
inline long long query(int index,int l,int r)
{
int mid;
if (Tree[index].l == l && Tree[index].r == r) return Tree[index].sum;
pushdown(index);
mid = (Tree[index].l + Tree[index].r) >> ;
if (mid >= r) return query(index<<,l,r);
else if (mid + <= l) return query(index<<|,l,r);
else return query(index<<,l,mid) + query(index<<|,mid+,r);
}
} T; inline void add(int u,int v)
{
tot++;
e[tot] = (Edge){v,head[u]};
head[u] = tot;
}
inline void dfs1(int x)
{
int i,y;
size[x] = ;
for (i = head[x]; i; i = e[i].nxt)
{
y = e[i].to;
if (fa[x] != y)
{
fa[y] = x;
dep[y] = dep[x] + ;
dfs1(y);
size[x] += size[y];
if (size[y] > size[son[x]]) son[x] = y;
}
}
}
inline void dfs2(int x,int tp)
{
int i,y;
top[x] = tp;
dfn[x] = ++timer;
pos[timer] = x;
if (son[x]) dfs2(son[x],tp);
for (i = head[x]; i; i = e[i].nxt)
{
y = e[i].to;
if (fa[x] != y && son[x] != y) dfs2(y,y);
}
}
inline long long query(int x)
{
long long ans = ;
int tx = top[x];
while (tx != )
{
ans += T.query(,dfn[tx],dfn[x]);
x = fa[tx]; tx = top[x];
}
ans += T.query(,,dfn[x]);
return ans;
} int main() { read(n); read(q);
for (i = ; i <= n; i++) read(a[i]);
for (i = ; i < n; i++)
{
read(x); read(y);
add(x,y);
add(y,x);
}
dfs1();
dfs2(,); T.build(,,timer);
while (q--)
{
read(opt);
if (opt == )
{
read(x); read(val);
T.add1(,dfn[x],val);
}
if (opt == )
{
read(x); read(val);
T.add2(,dfn[x],dfn[x]+size[x]-,val);
}
if (opt == )
{
read(x);
writeln(query(x));
}
} return ; }

【HAOI 2015】 树上操作的更多相关文章

  1. cogs 1963. [HAOI 2015] 树上操作 树链剖分+线段树

    1963. [HAOI 2015] 树上操作 ★★★☆   输入文件:haoi2015_t2.in   输出文件:haoi2015_t2.out   简单对比时间限制:1 s   内存限制:256 M ...

  2. [bzoj 4034][HAOI 2015]树上操作

    Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中 ...

  3. 洛谷P3178[HAOI]2015 树上操作

    题目 树剖裸题,这个题更可以深刻的理解树剖中把树上的节点转换为区间的思想. 要注意在区间上连续的节点,一定是在一棵子树中. #include <bits/stdc++.h> #define ...

  4. [HAOI 2015]树上染色

    Description 题库链接 给出一棵 \(n\) 个节点的树,边有权值.让你将树上 \(k\) 个点染黑,剩余 \(n-k\) 个点染白.染色后记一种染色方案的价值为黑点间两两距离和以及白点间两 ...

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

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

  6. HAOI2015 树上操作

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

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

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

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

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

  9. 树剖||树链剖分||线段树||BZOJ4034||Luogu3178||[HAOI2015]树上操作

    题面:P3178 [HAOI2015]树上操作 好像其他人都嫌这道题太容易了懒得讲,好吧那我讲. 题解:第一个操作和第二个操作本质上是一样的,所以可以合并.唯一值得讲的点就是:第二个操作要求把某个节点 ...

  10. P3178 [HAOI2015]树上操作

    P3178 [HAOI2015]树上操作 思路 板子嘛,其实我感觉树剖没啥脑子 就是debug 代码 #include <bits/stdc++.h> #define int long l ...

随机推荐

  1. UVA 11090 判负圈问题

    题目链接http://vjudge.net/problem/viewProblem.action?id=34650 题目大意: 给定n个点m条边的加权有向图,求平均权值最小的回路.平均权值=路径权值之 ...

  2. [Vijos] 天才的记忆

    背景 神仙飞啊飞 描述 从前有个人名叫W and N and B,他有着天才般的记忆力,他珍藏了许多许多的宝藏.在他离世之后留给后人一个难题(专门考验记忆力的啊!),如果谁能轻松回答出这个问题,便可以 ...

  3. 解决ssh无操作自动断开[转载,已经验证]

    用SSH远程,如果几分钟没有任何操作,连接就会断开,必须重新登陆才行,非常麻烦,一般修改2个地方3项即可解决问题: 1.终端键入:echo $TMOUT       如果显示空白,表示没有设置,等于使 ...

  4. 牛客网暑期ACM多校训练营(第三场)J 多边形与圆相交的面积

    链接:https://www.nowcoder.com/acm/contest/141/J 题目描述 Eddy has graduated from college. Currently, he is ...

  5. S5700&S5710 产品文档 : 配置

    http://support.huawei.com/hdx/hdx.do?docid=SC0000699332&lang=zh&path=PBI1-C103367%2FPBI1-C10 ...

  6. Git入门使用

    Git入门使用 安装Git 软件包如: Git-2.7.2-32-bit_setup.1457942412.exe TortoiseGit-1.8.12.0-64bit.msi 安装时候,直接点下一步 ...

  7. Java反射常用示例

    package xmq.study.reflection; import java.lang.annotation.Annotation; import java.lang.reflect.Const ...

  8. cocoapods应用第一部分-xcode创建.framework相关

    问题的提出: 随着项目的越来越大,可能会出现好几个团队共同维护一个项目的情况,比如:项目组A负责当中的A块,项目组B负责当中的B块.....这几块彼此之间既独立,也相互联系.对于这样的情况,能够採用约 ...

  9. mysql innodb插入意向锁

    innodb中有插入意向锁.专门针对insert,假设插入前,该间隙已经由gap锁,那么Insert会申请插入意向锁. 那么这个插入意向锁的作用是什么? 1.为了唤起等待.由于该间隙已经有锁,插入时必 ...

  10. spring理解一

    spring基本工作原理例如以下: 1.查找bean配置文件 2.载入bean配置文件并解析生成中间表示BeanDefinition 3.注冊beanDefinition 4.假设是单例或lazy-i ...