4034: [HAOI2015]树上操作

链接

思路:

  树链剖分。操作:单点修改,路径查询,子树修改。

代码:

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype> using namespace std; const int N = ;
typedef long long LL; struct Edge{
int to,nxt;
Edge() {}
Edge(int a,int b) {to = a,nxt = b;}
}e[N<<];
int head[N],tot;
LL sum[N<<],tag[N<<],w[N],data[N];
int pos[N],siz[N],son[N],bel[N],deth[N],fa[N];
int tn; inline int read() {
int x = ,f = ;char ch = getchar();
for (; !isdigit(ch); ch=getchar()) if(ch=='-') f = -;
for (; isdigit(ch); ch=getchar()) x = x*+ch-'';
return x * f;
}
void add_edge(int u,int v) {
e[++tot] = Edge(v,head[u]);head[u] = tot;
e[++tot] = Edge(u,head[v]);head[v] = tot;
}
void dfs1(int u,int pa) {
siz[u] = ;
deth[u] = deth[pa] + ;
fa[u] = pa;
for (int i=head[u]; i; i=e[i].nxt) {
int v = e[i].to;
if (v==pa) continue;
dfs1(v,u);
siz[u] += siz[v];
if (!son[u] || siz[son[u]]<siz[v]) son[u] = v;
}
}
void dfs2(int u,int top) {
bel[u] = top;
pos[u] = ++tn;
data[pos[u]] = w[u];
if (!son[u]) return;
dfs2(son[u],top);
for (int i=head[u]; i; i=e[i].nxt) {
int v = e[i].to;
if (v==fa[u] || v==son[u]) continue;
dfs2(v,v);
}
} #define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1 void pushup(int rt) {
sum[rt] = sum[rt<<] + sum[rt<<|];
}
void pushdown(int rt,int len) {
if (tag[rt]) {
sum[rt<<] += 1ll * tag[rt] * (len-len/);tag[rt<<] += tag[rt];
sum[rt<<|] += 1ll * tag[rt] * (len/);tag[rt<<|] += tag[rt];
tag[rt] = ;
}
}
void build(int l,int r,int rt) {
if (l==r) {
sum[rt] = data[l];
return ;
}
int mid = (l + r) / ;
build (lson);
build (rson);
pushup(rt);
}
void update(int l,int r,int rt,int L,int R,LL x) {
if (L <= l && r <= R) {
sum[rt] += 1ll * (r - l + ) * x;
tag[rt] += x;
return ;
}
pushdown(rt,r-l+);
int mid = (l + r) / ;
if (L <= mid) update(lson,L,R,x);
if (R > mid) update(rson,L,R,x);
pushup(rt);
}
LL query(int l,int r,int rt,int L,int R) {
if (L <= l && r <= R) {
return sum[rt];
}
int mid = (l + r) / ;
LL ret = ;
pushdown(rt,r-l+);
if (L <= mid) ret += query(lson,L,R);
if (R > mid) ret += query(rson,L,R);
return ret;
}
void Ask(int x,int y) {
LL ans = ;
while (bel[x] != bel[y]) {
if (deth[bel[x]] < deth[bel[y]]) swap(x,y);
ans += query(,tn,,pos[bel[x]],pos[x]);
x = fa[bel[x]];
}
if (deth[x] < deth[y]) swap(x,y);
ans += query(,tn,,pos[y],pos[x]);
printf("%lld\n",ans);
}
int main() {
int n = read(),m = read();
for (int i=; i<=n; ++i) w[i] = read();
for (int i=; i<n; ++i) {
int u = read(),v = read();
add_edge(u,v);
}
dfs1(,);
dfs2(,);
build(,tn,);
LL a;
while (m--) {
int opt = read(),x = read();
if (opt == ) {
a = read();
update(,tn,,pos[x],pos[x],a);
}
else if (opt==) {
a = read();
update(,tn,,pos[x],pos[x]+siz[x]-,a);
}
else Ask(x,);
}
return ;
}

4034: [HAOI2015]树上操作的更多相关文章

  1. bzoj 4034: [HAOI2015]树上操作 树链剖分+线段树

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

  2. bzoj 4034: [HAOI2015]树上操作 (树剖+线段树 子树操作)

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

  3. BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )

    BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...

  4. [BZOJ]4034: [HAOI2015]树上操作

    [HAOI2015]树上操作 传送门 题目大意:三个操作 1:a,b,c b节点权值+c 2:a,b,c 以b为根的子树节点权值全部+c 3:a,b 查询b到根路径的权值和. 题解:树链剖分 操作1 ...

  5. bzoj 4034 [HAOI2015]树上操作 入栈出栈序+线段树 / 树剖 维护到根距离和

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

  6. BZOJ 4034 [HAOI2015]树上操作(欧拉序+线段树)

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

  7. BZOJ 4034: [HAOI2015]树上操作 [欧拉序列 线段树]

    题意: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a . 操作 3 :询问某个节点 x 到根的路径中所有点的点权和. 显然树链剖分可做 ...

  8. 4034. [HAOI2015]树上操作【树链剖分】

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

  9. bzoj 4034: [HAOI2015]树上操作——树链剖分

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

随机推荐

  1. UIWindow及程序启动的过程

    1.   UIWindow才有自发显示的功能, 一个程序之所以能显示东西,是因为有window !//  [self.window makeKeyAndVisible]; 2.   任何view的显示 ...

  2. 如何使用Nunit进行测试

    如何使用Nunit进行测试(Visual Studio 2017 comminity) 原文:如何使用Nunit进行测试(Visual Studio 2017 comminity) 一.环境 操作系统 ...

  3. TeamViewer 软件完全卸载

    TeamViewer 软件似乎用于商业环境中 - 彻底卸载 Windows 1. 检测为商业用途该软件似乎用于商业环境中.请注意:免费版仅供个人使用.您的会话将在 5 分钟后终止. 2.1 Close ...

  4. win2008 配置TLS1.2

    配置TLS1.2 提供两种方法, 选择其中一种就行了 1.手动设置 找到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProv ...

  5. word中已删除设置是否显示

        我们打开别人发过来的文档时经常会出现如下图所示,其实这个不是文档的异常,只是word设置显示了修订版标记,如果我们需要去除这个,只需要在审阅-修订功能下面选择显示最终版即可(测试用的10版,其 ...

  6. Python数字、字符串

    1. 数字 byte 在python3中最重要的特性是对文本和二进制数据做了更加清晰的区分,python3不会以任意隐式方式混用字节型和字符型,也因此在python3中不能拼接字符串和字节包(pyth ...

  7. TP5.0: 显示错误信息

    在TP5中,我们运行的代码有错误无法执行时,只显示页面错误,而不显示错误信息 对我我来讲是无法接受滴!!毕竟我还是个小渣渣,查看了百度,解决方案是: 在application/config,php中找 ...

  8. Torch.no_grad()影响MSE损失

    相关描述 https://discuss.pytorch.org/t/torch-no-grad-affecting-outputs-loss/28595/3 今天在训练网络的时候,发现mseloss ...

  9. C4C和CRM里获取当前登录用户分配的Organization Unit信息

    C4C 如何查看某个用户分配的组织单元ID: 在Employee的Organization Data区域内看到分配的组织名称,如下图红色下划线所示: 现在的需求就是使用ABSL获取当前登录用户分配的O ...

  10. IOS ScrollView的使用 and delegate

    ScrollView常用的属性设置 //设置内容尺寸 // CGFloat contentH=self.lastBtn.frame // .origin.y+self.lastBtn.frame.si ...