HDU - 3966

思路 :树链剖分就是可以把一个路径上的点映射成几段连续的区间上。这样对于连续的区间可以用线段树维护,

对于每一段连续的区间都可以通过top [ ]数组很快的找到这段连续区间的头。跳的过程类似于 lca ,但这里 要注意的是

每一个点只属于一条链。 (重载运算符时要注意   node 一个 新的结点,不要 乱用*this 指针)

#include<bits/stdc++.h>
using namespace std;
#define MID int m = (l+r)/2
#define maxn 56789
#define inf 0x3f3f3f3f
struct node
{
int sum,lazy,cnt;
node()
{
sum=lazy=cnt=0;
}
node operator+(const node &a)const
{
node ret;
ret.sum=a.sum+sum;
ret.cnt=a.cnt+cnt;
return ret;
}
} tree[maxn*4];
char str[12];
vector<int>edge[maxn];
int data[maxn],n,m,id[maxn],fa[maxn],u,ans;
int son[maxn],top[maxn],tid[maxn],cnt,v,ad;
int deep[maxn],siz[maxn],id_data[maxn],q;
void pushdown(int root)
{
if(tree[root].lazy==0)return ;
tree[root*2].lazy+=tree[root].lazy;
tree[root*2+1].lazy+=tree[root].lazy;
tree[root*2].sum+=tree[root*2].cnt*tree[root].lazy;
tree[root*2+1].sum+=tree[root*2+1].cnt*tree[root].lazy;
tree[root].lazy=0;
}
void bulid(int root,int l,int r)
{
tree[root].lazy=0;
if(l==r)
{
tree[root].sum=id_data[l];
tree[root].cnt=1;
return ;
}
MID;
bulid(root*2,l,m);
bulid(root*2+1,m+1,r);
tree[root]=tree[root*2]+tree[root*2+1];
}
void updata(int root,int l,int r,int L,int R,int ad)
{
if(r<L||l>R)return;
if(L<=l&&r<=R)
{
tree[root].sum+=tree[root].cnt*ad;
tree[root].lazy+=ad;
return ;
}
pushdown(root);
MID;
updata(root*2,l,m,L,R,ad);
updata(root*2+1,m+1,r,L,R,ad);
tree[root]=tree[root*2]+tree[root*2+1];
}
void query(int root,int l,int r,int L,int R)
{
if(r<L||l>R)return ;
if(L<=l&&r<=R)
{
ans+=tree[root].sum;
return;
}
pushdown(root);
MID;
query(root*2,l,m,L,R);
query(root*2+1,m+1,r,L,R);
}
void dfs1(int u,int pre,int ide)
{
son[u]=-1,siz[u]=1;
deep[u]=ide,fa[u]=pre;
for(int i=0; i<edge[u].size(); i++)
{
int v=edge[u][i];
if(v==pre)continue;
dfs1(v,u,ide+1);
if(son[u]==-1||siz[son[u]]<siz[v])
son[u]=v;
}
}
void dfs2(int u,int tp)
{
top[u]=tp, tid[u]=++cnt;
id_data[cnt]=data[u];
if(son[u]!=-1)dfs2(son[u],tp);
for(int i=0; i<edge[u].size(); i++)
{
int v=edge[u][i];
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
void solve(int x,int y,int ad)
{
int tx=top[x],ty=top[y];
while(tx!=ty)
{
if(deep[tx]<deep[ty])swap(x,y),swap(tx,ty);
updata(1,1,n,tid[tx],tid[x],ad);
x=fa[tx],tx=top[x];
}
if(deep[x]<deep[y])swap(x,y);
updata(1,1,n,tid[y],tid[x],ad);
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&q))
{
cnt=0;
for(int i=1; i<=n; i++)
{
scanf("%d",&data[i]);
edge[i].clear();
}
while(m--)
{
scanf("%d%d",&u,&v);
edge[u].push_back(v);
edge[v].push_back(u);
}
dfs1(1,0,1);
dfs2(1,1);
bulid(1,1,n);
while(q--)
{
scanf("%s",str);
if(str[0]=='I')
{
scanf("%d%d%d",&u,&v,&ad);
solve(u,v,ad);
}
else if(str[0]=='D')
{
scanf("%d%d%d",&u,&v,&ad);
solve(u,v,-ad);
}
else
{
scanf("%d",&u);
ans=0;
query(1,1,n,tid[u],tid[u]);
printf("%d\n",ans);
}
}
}
return 0;
}

  

Aragorn's Story HDU - 3966 -树剖模板的更多相关文章

  1. A - Aragorn's Story HDU - 3966 树剖裸题

    这个题目是一个比较裸的树剖题,很好写. http://acm.hdu.edu.cn/showproblem.php?pid=3966 #include <cstdio> #include ...

  2. HDU 3966 (树链剖分+线段树)

    Problem Aragorn's Story (HDU 3966) 题目大意 给定一颗树,有点权. 要求支持两种操作,将一条路径上的所有点权值增加或减少ai,询问某点的权值. 解题分析 树链剖分模板 ...

  3. AC日记——Aragorn's Story HDU 3966

    Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. 【树链剖分】洛谷P3384树剖模板

    题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式 ...

  5. 洛谷树剖模板题 P3384 | 树链剖分

    原题链接 对于以u为根的子树,后代节点的dfn显然比他的dfn大,我们可以记录一下回溯到u的dfn,显然这两个dfn构成了一个连续区间,代表u及u的子树 剩下的就和树剖一样了 #include< ...

  6. HDU 3966 树链剖分+树状数组 模板

    Aragorn's Story Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  7. hdu 3966(树链剖分+线段树区间更新)

    传送门:Problem 3966 https://www.cnblogs.com/violet-acmer/p/9711441.html 学习资料: [1]线段树区间更新:https://blog.c ...

  8. HDU 3966 /// 树链剖分+树状数组

    题意: http://acm.hdu.edu.cn/showproblem.php?pid=3966 给一棵树,并给定各个点权的值,然后有3种操作: I x y z : 把x到y的路径上的所有点权值加 ...

  9. hdu 3966 树链剖分

    思路:树链剖分入门题,我这门入得好苦啊,程序很快写出来了,可是在LCA过程中把update函数里的左右边界位置写反了,一直RE到死. #pragma comment(linker, "/ST ...

随机推荐

  1. spring security oauth2 client_credentials模

    spring security oauth2 client_credentials模 https://www.jianshu.com/p/1c3eea71410e 序 本文主要简单介绍一下spring ...

  2. 用beam实现连接kafka和elasticSearch示例 在flink平台运行

    示例实现beam用java编程,监听kafka的testmsg主题,然后将收取到的单词,按5秒做一次统计.结果输出到outputmessage 的kafka主题,同时同步到elasticSearch. ...

  3. 礼物(中国剩余定理+拓展gcd求逆元+分治=拓展Lucus)

    礼物 题意: 求\[C(n,m)\ \%\ p\] \(n,m,p\le 10^9\),且若\(p=\prod_{i=1}^{k}{p_i}^{c_i}\),则\(\forall i\in [1..k ...

  4. python list的使用

    list列表的常用方法有: #!/usr/bin/env python # -*- coding:utf- -*- #以下方法全在python2..x版本运行,请3.x以上的小伙伴们在print(放入 ...

  5. 模型评估【PR|ROC|AUC】

    这里主要讲的是对分类模型的评估. 1.准确率(Accuracy) 准确率的定义是:[分类正确的样本] / [总样本个数],其中分类正确的样本是不分正负样本的 优点:简单粗暴 缺点:当正负样本分布不均衡 ...

  6. Numpy 系列(八)- 广播机制

    什么是广播 我们都知道,Numpy中的基本运算(加.减.乘.除.求余等等)都是元素级别的,但是这仅仅局限于两个数组的形状相同的情况下. 可是大家又会发现,如果让一个数组加1的话,结果时整个数组的结果都 ...

  7. .net Core 下数据库访问

    SqlSugar :是一款高性能(达到ADO.NET最高性能水平)SqlSugar :是除EF外拉姆达解析最完善的ORM,多表 .UnionALL. 交叉子查询.真实的批量操作和分页SqlSugar ...

  8. freemarker和thymeleaf的使用样例

    最近需要对公司项目首页使用Java模板重做,以提高首屏加载速度和优化SEO. 在选择模板时发现freemarker和thymeleaf最为常用. 两者最大的区别在于语法,对性能方面未作测试,具体性能测 ...

  9. react实战项目开发(2) react几个重要概念以及JSX语法

    前言 前面我们已经学习了利用官方脚手架搭建一套可以应用在生产环境下的React开发环境.那么今天这篇文章主要先了解几个react重要的概念,以及讲解本文的重要知识JSX语法 React重要概念 [思想 ...

  10. v-charts 和 websocket实现数据展示动态推送

    v-charts https://v-charts.js.org/#/ ELEMENT力作: 在使用 echarts 生成图表时,经常需要做繁琐的数据类型转化.修改复杂的配置项,v-charts 的出 ...