Codevs 4633 [Mz]树链剖分练习
4633 [Mz]树链剖分练习
时间限制: 1 s 空间限制: 64000 KB 题目等级 : 大师 Master
给定一棵结点数为n的树,初始点权均为0,有依次q个操作,每次操作有三个参数a,b,c,当a=1时,表示给b号结点到c号结点路径上的所有点(包括b,c,下同)权值都增加1,当a=2时,表示询问b号结点到c号结点路径上的所有点权值之和。
第一行,一个正整数n。
接下来n-1行,每行一对正整数x,y,表示x号结点和y号结点之间有一条边。
第n+1行,一个正整数q。
最后q行,每行一组正整数a,b,c,表示操作的三个参数。b和c可能相等。
保证数据都是合法的。
若干行,每行一个非负整数表示答案。
5
1 2
2 3
1 4
2 5
5
1 4 5
2 1 5
1 1 3
2 5 3
2 4 3
3
4
6
共有10个测试点,对于第i个测试点,当1<=i<=4时,n=q=10^i,当5<=i<=10时,n=q=10000*i。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 10000*10
struct Edge{ int to,next,value; }e[maxn*+];
struct Node{ int l,r,sum,lazy; }tre[maxn*];
int dep[maxn],pos[maxn],size[maxn],son[maxn],fa[maxn];
int top[maxn],head[maxn],tot=,n,visx;
void Add_Edge(int u,int v){
e[++tot].to=v;e[tot].next=head[u];
head[u]=tot;
}
void DFS_First(int now,int pre,int deepth){
fa[now]=pre;size[now]=;dep[now]=deepth;
for(int i=head[now];i;i=e[i].next){
int v=e[i].to;
if(v!=pre&&!dep[v]){
DFS_First(v,now,deepth+);
size[now]+=size[v];
if(!son[now]||size[son[now]]<size[v])
son[now]=v;
}
}
}
void DFS_Second(int now,int Top){
pos[now]=++visx;top[now]=Top;
if(son[now])DFS_Second(son[now],Top);
for(int i=head[now];i;i=e[i].next){
int v=e[i].to;
if(v!=son[now]&&v!=fa[now])DFS_Second(v,v);
}
}
void Build(int now,int l,int r){
tre[now].l=l;tre[now].r=r;
if(l==r)return;
int mid=(l+r)>>;
Build(now<<,l,mid);Build(now<<|,mid+,r);
}
void down(int now){
int k=tre[now].lazy;
tre[now<<].lazy+=k;tre[now<<|].lazy+=k;
tre[now].lazy=;
tre[now<<].sum+=k*(tre[now<<].r-tre[now<<].l+);
tre[now<<|].sum+=k*(tre[now<<|].r-tre[now<<|].l+);
}
int query(int now,int l,int r){
if(l<=tre[now].l&&tre[now].r<=r)return tre[now].sum;
if(tre[now].lazy)down(now);
int ans=,mid=(tre[now].l+tre[now].r)>>;
if(mid>=l)ans+=query(now<<,l,r);
if(mid<r)ans+=query(now<<|,l,r);
tre[now].sum=tre[now<<].sum+tre[now<<|].sum;
return ans;
}
int QuerySum(int u,int v){
int ans=;
while(top[u]!=top[v]){
if(dep[top[u]] < dep[top[v]])swap(u,v);
ans+=query(,pos[top[u]],pos[u]);
u=fa[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
ans+=query(,pos[u],pos[v]);
return ans;
}
void UpDate(int now,int l,int r){
if(l<=tre[now].l&&tre[now].r<=r){
tre[now].lazy++;
tre[now].sum+=tre[now].r-tre[now].l+;
return ;
}
if(tre[now].lazy)down(now);
int mid=(tre[now].l+tre[now].r)/;
if(mid>=l)UpDate(now<<,l,r);
if(mid<r)UpDate(now<<|,l,r);
tre[now].sum=tre[now<<].sum+tre[now<<|].sum;
return ;
}
void Change(int u,int v){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
UpDate(,pos[top[u]],pos[u]);
u=fa[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
UpDate(,pos[u],pos[v]);
}
int main(){
scanf("%d",&n);
int q,x,y,z;
for(int i=,u,v;i<n;i++){
scanf("%d%d",&u,&v);
Add_Edge(u,v);Add_Edge(v,u);
}
DFS_First(,,);
DFS_Second(,);
Build(,,n); scanf("%d",&q);
while(q--){
scanf("%d%d%d",&x,&y,&z);
if(x==)Change(y,z);
else printf("%d\n",QuerySum(y,z));
}
return ;
}
Codevs 4633 [Mz]树链剖分练习的更多相关文章
- CODE[VS]4633:Mz树链剖分练习
Description 给定一棵结点数为n的树,初始点权均为0,有依次q个操作,每次操作有三个参数a,b,c,当a=1时,表示给b号结点到c号结点路径上的所有点(包括b,c,下同)权值都增加1,当a= ...
- codevs 1228 苹果树 树链剖分讲解
题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...
- [CodeVS4633][Mz]树链剖分练习
思路: 轻重链剖分+线段树. #include<cstdio> #include<vector> #include<cstring> ; std::vector&l ...
- 【最近公共祖先】【树链剖分】CODEVS 1036 商务旅行
树链剖分求lca模板.O(log(n)),就是不倍增嘛~ #include<cstdio> #include<algorithm> using namespace std; # ...
- 【BZOJ-3589】动态树 树链剖分 + 线段树 + 线段覆盖(特殊的技巧)
3589: 动态树 Time Limit: 30 Sec Memory Limit: 1024 MBSubmit: 405 Solved: 137[Submit][Status][Discuss] ...
- NOIP2015 运输计划 - 二分 + 树链剖分 / (倍增 + 差分)
BZOJ CodeVS Uoj 题目大意: 给一个n个点的边带权树,给定m条链,你可以选择树中的任意一条边,将它置为0,使得最长的链长最短. 题目分析: 最小化最大值,二分. 二分最短长度mid,将图 ...
- 2020牛客NOIP赛前集训营-提高组(第三场) C - 牛半仙的妹子Tree (树链剖分)
昨天教练问我:你用树剖做这道题,怎么全部清空状态呢? 我:???不是懒标记就完了??? 教练:树剖不是要建很多棵线段树吗,不止log个,你要一个一个清? 我:为什么要建很多棵线段树? ...
- BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2050 Solved: 817[Submit][Status ...
- BZOJ 1984: 月下“毛景树” [树链剖分 边权]
1984: 月下“毛景树” Time Limit: 20 Sec Memory Limit: 64 MBSubmit: 1728 Solved: 531[Submit][Status][Discu ...
随机推荐
- Tomcat:javax.management.InstanceNotFoundException: com.alibaba.druid:type=DruidDataSourceStat异常
问题: 在关闭tomcat时: Tomat报出一下异常:ERROR [com.alibaba.druid.stat.DruidDataSourceStatManager] – unregister m ...
- 利用DOM的方式点击切换图片及修改文字
本案例主要学习理解,用到的几个DOM方法 01.getAttribute()方法,获取元素的属性值 02.setAttribute('src',source) 方法,用后边的值修改前边这个元素的属性值 ...
- java NIO简介
1)java nio简介 nio 是 java New IO 的简称,在 jdk1.4 里提供的新 api . Sun 官方标榜的特性如有:为所有的原始类型提供 (Buffer) 缓存支持:字符集编码 ...
- opencv使用日记之一:平台搭建Mat类以及图像的读取修改
平台搭建就摸了一整天时间,真的是...不说了,最后我选择的是 opencv3.0(2015/06/04) + win7 + vs2012 注意opencv的版本不同导入的库文件是不一样的,所以请 ...
- 6 json和ajax传递api数据
1 2 3 4 https://swapi.co/ <h1>Hello Reqwest!</h1> <script> var a = {} reqwest({ ur ...
- BZOJ 3420: Poi2013 Triumphal arch
二分答案 第二个人不会走回头路 那么F[i]表示在i的子树内(不包括i)所需要的额外步数 F[1]==0表示mid可行 k可能为0 #include<cstdio> #include< ...
- TCP/IP网络编程之套接字与标准I/O
标准I/O函数 标准标准I/O函数有两个优点: 标准I/O函数具有良好的移植性 标准I/O函数可以利用缓冲提高性能 关于移植性无需过多解释,不仅是I/O函数,所有标准函数都具有良好的移植性.因为,为了 ...
- JVM内存管理:深入Java内存区域与OOM
Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来. 概述: 对于从事C.C++程序开发的开发人员来说,在内存管理领域,他们即是拥有最高权力的皇帝 ...
- Python框架之Django学习笔记(九)
模型 之前,我们用 Django 建造网站的基本途径: 建立视图和 URLConf . 正如我们所阐述的,视图负责处理一些主观逻辑,然后返回响应结果. 作为例子之一,我们的主观逻辑是要计算当前的日期和 ...
- Python基础-week03 集合 , 文件操作 和 函数详解
一.集合及其运算 1.集合的概念 集合是一个无序的,不重复的数据组合,它的主要作用如下 *去重,把一个列表变成集合,就自动去重了 *关系测试,测试两组数据之前的交集.并集.差集.子集.父级.对称差集, ...