4633 [Mz]树链剖分练习

时间限制: 1 s    空间限制: 64000 KB    题目等级 : 大师 Master

题目描述 Description

给定一棵结点数为n的树,初始点权均为0,有依次q个操作,每次操作有三个参数a,b,c,当a=1时,表示给b号结点到c号结点路径上的所有点(包括b,c,下同)权值都增加1,当a=2时,表示询问b号结点到c号结点路径上的所有点权值之和。

输入描述 Input Description

第一行,一个正整数n。

接下来n-1行,每行一对正整数x,y,表示x号结点和y号结点之间有一条边。

第n+1行,一个正整数q。

最后q行,每行一组正整数a,b,c,表示操作的三个参数。b和c可能相等。

保证数据都是合法的。

输出描述 Output Description

若干行,每行一个非负整数表示答案。

样例输入 Sample Input

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

样例输出 Sample Output

3

4

6

数据范围及提示 Data Size & Hint

共有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]树链剖分练习的更多相关文章

  1. CODE[VS]4633:Mz树链剖分练习

    Description 给定一棵结点数为n的树,初始点权均为0,有依次q个操作,每次操作有三个参数a,b,c,当a=1时,表示给b号结点到c号结点路径上的所有点(包括b,c,下同)权值都增加1,当a= ...

  2. codevs 1228 苹果树 树链剖分讲解

    题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...

  3. [CodeVS4633][Mz]树链剖分练习

    思路: 轻重链剖分+线段树. #include<cstdio> #include<vector> #include<cstring> ; std::vector&l ...

  4. 【最近公共祖先】【树链剖分】CODEVS 1036 商务旅行

    树链剖分求lca模板.O(log(n)),就是不倍增嘛~ #include<cstdio> #include<algorithm> using namespace std; # ...

  5. 【BZOJ-3589】动态树 树链剖分 + 线段树 + 线段覆盖(特殊的技巧)

    3589: 动态树 Time Limit: 30 Sec  Memory Limit: 1024 MBSubmit: 405  Solved: 137[Submit][Status][Discuss] ...

  6. NOIP2015 运输计划 - 二分 + 树链剖分 / (倍增 + 差分)

    BZOJ CodeVS Uoj 题目大意: 给一个n个点的边带权树,给定m条链,你可以选择树中的任意一条边,将它置为0,使得最长的链长最短. 题目分析: 最小化最大值,二分. 二分最短长度mid,将图 ...

  7. 2020牛客NOIP赛前集训营-提高组(第三场) C - 牛半仙的妹子Tree (树链剖分)

    昨天教练问我:你用树剖做这道题,怎么全部清空状态呢?    我:???不是懒标记就完了???    教练:树剖不是要建很多棵线段树吗,不止log个,你要一个一个清?    我:为什么要建很多棵线段树? ...

  8. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

  9. BZOJ 1984: 月下“毛景树” [树链剖分 边权]

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1728  Solved: 531[Submit][Status][Discu ...

随机推荐

  1. 洛谷 3567/BZOJ 3524 Couriers

    3524: [Poi2014]Couriers Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 2895  Solved: 1189[Submit][S ...

  2. JS - Object.create(prototype)方法

    用Object.create(prototype)方法创建一个对象,这个对象的原型将指向这个传入的prototype参数

  3. Mbps、Kbps、bps、kb、mb区别和换算

    Mbps 即 Milionbit pro second(百万位每秒) Kbps 即 Kilobit pro second(千位每秒) bps 即 bit pro second(位每秒) 速度单位,bi ...

  4. 震惊!几道Python 理论面试题,Python面试题No18

    本面试题题库,由公号:非本科程序员 整理发布 第1题: 简述解释型和编译型编程语言? 解释型语言编写的程序不需要编译,在执行的时候,专门有一个解释器能够将VB语言翻译成机器语言,每个语句都是执行的时候 ...

  5. 学习Pytbon第三天,用户输入

    _username ='dream' #定义用户名 _password ='dream123'#定义用户密码username = input("username:")#请输入用户名 ...

  6. ARM Linux内核源码剖析索引

    start_kernel -->asm-offset.h 生成 -->proc_info_list   -->machine_desc -->__vet_atags --> ...

  7. POJ:2185-Milking Grid(KMP找矩阵循环节)

    Milking Grid Time Limit: 3000MS Memory Limit: 65536K Description Every morning when they are milked, ...

  8. Kubernetes添加带Quota限额的CephFS StorageClass

    1. 在Ceph上为Kubernetes创建一个文件系统 # ceph osd pool create cephfs_data # ceph osd pool create cephfs_metada ...

  9. U10783 名字被和谐了

    U10783 名字被和谐了 题目背景 众所周知,我们称g是a的约数,当且仅当g是正数且a mod g = 0. 众所周知,若g既是a的约数也是b的约数,我们称g是a.b的一个公约数. 众所周知,a.b ...

  10. hadoop ha集群搭建

    集群配置: jdk1.8.0_161 hadoop-2.6.1 zookeeper-3.4.8 linux系统环境:Centos6.5 3台主机:master.slave01.slave02 Hado ...