http://www.lydsy.com/JudgeOnline/problem.php?id=4034

https://www.luogu.org/problemnew/show/P3178

有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个
操作,分为三种:
操作 1 :把某个节点 x 的点权增加 a 。
操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
操作 3 :询问某个节点 x 到根的路径中所有点的点权和。

树剖板子。不会写树链剖分的请看:http://www.cnblogs.com/luyouqi233/p/7886709.html

试图默写结果被1和l搞反然后gg。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int N=1e5+;
inline int read(){
int X=,w=;char ch=;
while(ch<''||ch>''){w|=ch=='-';ch=getchar();}
while(ch>=''&&ch<='')X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct node{
int to,nxt;
}edge[*N];
int head[N],cnt,tot,n,q;
inline void add(int u,int v){
edge[++cnt].to=v;edge[cnt].nxt=head[u];head[u]=cnt;
}
int fa[N],son[N],size[N],val[N],dep[N],idx[N],pos[N],top[N];
ll sum[*N],lazy[*N];
void dfs1(int u){
size[u]=;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==fa[u])continue;
fa[v]=u;dep[v]=dep[u]+;
dfs1(v);
size[u]+=size[v];
if(!son[u]||size[son[u]]<size[v])son[u]=v;
}
}
void dfs2(int u,int anc){
pos[u]=++tot;
idx[tot]=u;
top[u]=anc;
if(!son[u])return;
dfs2(son[u],anc);
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
void init(){
dep[]=;
dfs1();
dfs2(,);
}
void push(int a,int l,int r){
int mid=(l+r)>>;
if(lazy[a]){
lazy[a*]+=lazy[a];
lazy[a*+]+=lazy[a];
sum[a*]+=(mid-l+)*lazy[a];
sum[a*+]+=(r-mid)*lazy[a];
lazy[a]=;
}
}
void build(int a,int l,int r){
if(l==r){
sum[a]=val[idx[l]];
return;
}
int mid=(l+r)>>;
build(a*,l,mid);
build(a*+,mid+,r);
sum[a]=sum[a*]+sum[a*+];
}
ll query(int a,int l,int r,int l1,int r1){
if(r1<l||r<l1)return ;
if(l1<=l&&r<=r1)return sum[a];
int mid=(l+r)>>;
push(a,l,r);
return query(a*,l,mid,l1,r1)+query(a*+,mid+,r,l1,r1);
}
ll pathquery(int x,int y){
ll res=;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]])swap(x,y);
res+=query(,,n,pos[top[x]],pos[x]);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
res+=query(,,n,pos[x],pos[y]);
return res;
}
void modify(int a,int l,int r,int l1,int r1,ll p){
if(r1<l||r<l1)return;
if(l1<=l&&r<=r1){
sum[a]+=(r-l+)*p;
lazy[a]+=p;
return;
}
int mid=(l+r)>>;
push(a,l,r);
modify(a*,l,mid,l1,r1,p);
modify(a*+,mid+,r,l1,r1,p);
sum[a]=sum[a*]+sum[a*+];
}
int main(){
n=read(),q=read();
for(int i=;i<=n;i++)val[i]=read();
for(int i=;i<n;i++){
int u=read(),v=read();
add(u,v);add(v,u);
}
init();
build(,,n);
while(q--){
int op=read();
if(op==){
int x=read(),a=read();
modify(,,n,pos[x],pos[x],a);
}
if(op==){
int x=read(),a=read();
modify(,,n,pos[x],pos[x]+size[x]-,a);
}
if(op==){
int x=read();
printf("%lld\n",pathquery(x,));
}
}
return ;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

BZOJ4034:[HAOI2015]树上操作——题解的更多相关文章

  1. bzoj4034: [HAOI2015]树上操作(树剖)

    4034: [HAOI2015]树上操作 题目:传送门 题解: 树剖裸题: 麻烦一点的就只有子树修改(其实一点也不),因为子树编号连续啊,直接改段(记录编号最小和最大) 开个long long 水模版 ...

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

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

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

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

  4. BZOJ4034 [HAOI2015]树上操作 树链剖分

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ4034 题意概括 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三 ...

  5. BZOJ4034: [HAOI2015]树上操作

    这题把我写吐了...代码水平还是太弱鸡了啊... 这题就是先给你一些点,以及点权.然后给你一些向边构成一颗树,树的根节点是1. 然后给定三个操作 第一个是把指定节点的权值+W 第二个是把指定节点X为根 ...

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

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

  7. [luogu3178][bzoj4034][HAOI2015]树上操作

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

  8. [bzoj4034][HAOI2015]树上操作——树状数组+dfs序

    Brief Description 您需要设计一种数据结构支持以下操作: 把某个节点 x 的点权增加 a . 把某个节点 x 为根的子树中所有点的点权都增加 a . 询问某个节点 x 到根的路径中所有 ...

  9. BZOJ4034 [HAOI2015]树上操作+DFS序+线段树

    参考:https://www.cnblogs.com/liyinggang/p/5965981.html 题意:是一个数据结构题,树上的,用dfs序,变成线性的: 思路:对于每一个节点x,记录其DFS ...

随机推荐

  1. dva webpack 利用require.context加载多个model

    dva redux数据管理都在models,根据业务不同models可能会有几十甚至上百的 [模块.js], 每次在index.js使用 app.model(require('./models/exa ...

  2. hdu1061Rightmost Digit(快速幂取余)

    Rightmost Digit Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  3. (python)leetcode刷题笔记 02 Add Two Numbers

    2. Add Two Numbers You are given two non-empty linked lists representing two non-negative integers. ...

  4. JSP页面中文乱码问题

    $.get()方法到服务器端中文乱码 在jsp页面使用encodeURI(“中文”),在服务器端进行解码 String name = req.getParameter("name" ...

  5. Memcache的客户端连接系列(四) PHP

    关键词: Memcached   PHP 客户端 声明:本文并非原创,转自华为云帮助中心的分布式缓存服务(Memcached)的用户指南.客户端连接方法通用,故摘抄过来分享给大家. PHP客户端 Re ...

  6. 【Linux 运维】linux系统修改主机名

    主机名的修改:  1.命名解释: [root@localhost~]# 分别代表: 用户名(root) 主机名(localhost) 当前路径(~,当前用户的home目录) 权限标志位(#代表root ...

  7. 讯飞云 API 语音听写 python3 调用例程

    #!/usr/bin/python3 # -*- coding: UTF-8 -*- import requests import time import gzip import urllib imp ...

  8. 机器学习之支持向量机(Support Vector Machine)

    转载请注明出处:http://www.cnblogs.com/Peyton-Li/ 支持向量机 支持向量机(support vector machines,SVMs)是一种二类分类模型.它的基本模型是 ...

  9. 【Coursera-ML-Notes】线性回归(下)

    模型表示 多变量的线性回归也叫做"多元线性回归".首先还是先明确几个符号的含义. \(x{^{(i)}_j}\):第i个训练样本的第j个特征,比如面积,楼层,客厅数 \(x^{(i ...

  10. STM32F4 编程手册学习1_编程模型

    STM32F4 programming manual_1 1. 处理器模式与特权等级 处理器模式分为以下两种: 线程模式: 用来执行应用软件: 处理器从reset出来时,进入线程模式: CONTROL ...