【bzoj3589】动态树 树链剖分+树链的并
题解:
树链剖分是显然的
问题在于求树链的并
比较简单的方法是
用线段树打标记覆盖,查询标记区间大小
Qlog^2n
代码:
#include <bits/stdc++.h>
using namespace std;
#define IL inline
#define rint register int
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
const int N=3e5;
const int N1=N*;
const int INF=1e9;
int n,l,cnt,dfn[N],size[N],fa[N],top[N],son[N],head[N],dep[N];
struct re{
int a,b;
}a[N*];
void arr(int x,int y)
{
a[++l].a=head[x];
a[l].b=y;
head[x]=l;
}
void dfs(int x,int y)
{
fa[x]=y; size[x]=;
int u=head[x];
dep[x]=dep[y]+;
while (u)
{
int v=a[u].b;
if (v!=y)
{
dfs(v,x);
if (size[v]>size[son[x]]) son[x]=v;
size[x]+=size[v];
}
u=a[u].a;
}
}
void dfs2(int x,int y)
{
dfn[x]=++cnt; top[x]=y;
if (!son[x]) return;
dfs2(son[x],y);
int u=head[x];
while (u)
{
int v=a[u].b;
if (v!=fa[x]&&v!=son[x]) dfs2(v,v);
u=a[u].a;
}
}
struct sgt{ int sum[N1],sum1[N1],lazy[N1],lazy1[N1];
#define mid ((h+t)/2)
IL void clear()
{
lazy1[]=-; sum1[]=;
}
IL int query()
{
return sum1[];
}
IL void down(int x,int h,int t)
{
if (lazy[x])
{
sum[x*]+=(mid-h+)*lazy[x];
sum[x*+]+=(t-mid)*lazy[x];
lazy[x*]+=lazy[x]; lazy[x*+]+=lazy[x];
lazy[x]=;
}
if (lazy1[x])
{
lazy1[x*]=lazy1[x*+]=lazy1[x];
if (lazy1[x]==) sum1[x*]=sum[x*],sum1[x*+]=sum[x*+];
else sum1[x*]=sum1[x*+]=;
lazy1[x]=;
}
}
IL void updata(int x)
{
sum[x]=sum[x*]+sum[x*+];
sum1[x]=sum1[x*]+sum1[x*+];
}
void change(int x,int h,int t,int h1,int t1,int k)
{
if (h1<=h&&t<=t1)
{
lazy[x]+=k; sum[x]+=(t-h+)*k; return;
}
down(x,h,t);
if (h1<=mid) change(x*,h,mid,h1,t1,k);
if (mid<t1) change(x*+,mid+,t,h1,t1,k);
updata(x);
}
void push(int x,int h,int t,int h1,int t1)
{
if (h1<=h&&t<=t1)
{
lazy1[x]=; sum1[x]=sum[x]; return;
}
down(x,h,t);
if (h1<=mid) push(x*,h,mid,h1,t1);
if (mid<t1) push(x*+,mid+,t,h1,t1);
updata(x);
}
}S;
void change(int x,int y)
{
int kk=dfn[x];
S.change(,,n,kk,kk+size[x]-,y);
}
void query(int x,int y)
{
int f1=top[x],f2=top[y];
while (top[x]!=top[y])
{
if (dep[f1]<dep[f2]) swap(f1,f2),swap(x,y);
S.push(,,n,dfn[f1],dfn[x]);
x=fa[f1]; f1=top[x];
}
if (dep[x]<dep[y]) swap(x,y);
S.push(,,n,dfn[y],dfn[x]);
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
ios::sync_with_stdio(false);
cin>>n;
rep(i,,n-)
{
int x,y; cin>>x>>y;
arr(x,y); arr(y,x);
}
dfs(,);
dfs2(,);
int m;
cin>>m;
rep(i,,m)
{
int kk,x,y,p;
cin>>kk;
if (!kk)
{
cin>>x>>y;
change(x,y);
} else
{
cin>>p;
rep(j,,p)
{
cin>>x>>y;
query(x,y);
}
int ans=S.query();
if (ans<) ans+=<<;
cout<<ans<<endl;
S.clear();
}
}
return ;
}
【bzoj3589】动态树 树链剖分+树链的并的更多相关文章
- hdu 3966 Aragorn's Story(树链剖分+树状数组/线段树)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题意: 给出一棵树,并给定各个点权的值,然后有3种操作: I C1 C2 K: 把C1与C2的路 ...
- Aragorn's Story 树链剖分+线段树 && 树链剖分+树状数组
Aragorn's Story 来源:http://www.fjutacm.com/Problem.jsp?pid=2710来源:http://acm.hdu.edu.cn/showproblem.p ...
- 洛谷 P3384 【模板】树链剖分-树链剖分(点权)(路径节点更新、路径求和、子树节点更新、子树求和)模板-备注结合一下以前写的题目,懒得写很详细的注释
P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节 ...
- 4.12 省选模拟赛 LCA on tree 树链剖分 树状数组 分析答案变化量
LINK:duoxiao OJ LCA on Tree 题目: 一道树链剖分+树状数组的神题. (直接nQ的暴力有50. 其实对于树随机的时候不难想到一个算法 对于x的修改 暴力修改到根. 对于儿子的 ...
- (简单) POJ 3321 Apple Tree,树链剖分+树状数组。
Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow ...
- Codeforces Round #425 (Div. 2) Problem D Misha, Grisha and Underground (Codeforces 832D) - 树链剖分 - 树状数组
Misha and Grisha are funny boys, so they like to use new underground. The underground has n stations ...
- HDU 3966 Aragorn's Story 树链剖分+树状数组 或 树链剖分+线段树
HDU 3966 Aragorn's Story 先把树剖成链,然后用树状数组维护: 讲真,研究了好久,还是没明白 树状数组这样实现"区间更新+单点查询"的原理... 神奇... ...
- bzoj1146整体二分+树链剖分+树状数组
其实也没啥好说的 用树状数组可以O(logn)的查询 套一层整体二分就可以做到O(nlngn) 最后用树链剖分让序列上树 #include<cstdio> #include<cstr ...
- HDU 5044 (树链剖分+树状数组+点/边改查)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5044 题目大意:修改链上点,修改链上的边.查询所有点,查询所有边. 解题思路: 2014上海网赛的变 ...
随机推荐
- 《超越C++标准库:Boost库导引》:序
序(Foreword) C++社区正在发生着一些美妙的事情.尽管C++仍然是世界上使用最广泛的编程语言,它依旧在变得更加强大而且易用.不信么?容我慢慢道来. 当前版本的标准C++是在1998年最终确定 ...
- shell中的dd命令使用详解
一.dd命令的解释 dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. 注意:指定数字的地方若以下列字符结尾,则乘以相应的数字:b=512:c=1:k=1024:w=2 参数注释: 1. ...
- Mudo C++网络库第十一章学习笔记
反思C++面向对象与虚函数 C++语言学习可以看<C++ Primer>这本书; 在C++中进行面向对象编程会遇到其他语言中不存在的问题, 其本质原因是C++ class是值语义, 而非对 ...
- Unity3D之IOS&Android收集Log文件
开发项目的时候尤其在处理与服务器交互这块,如果服务端程序看不到客户端请求的Log信息,那么无法修改BUG.在Windows上Unity会自动讲Log文件写入本地,但是在IOS和Android上确没有这 ...
- 微信小程序-聊天列表-角标
<div class="list-body" bindtap='openChat' data-Obj='{{oitem}}'> <!-- 头像 --> &l ...
- 使用GeoServer导出地图数据GeoJSON并应用
在项目中,需要使用乡镇街道的地图边界,之前一直使用的是百度地图或Echarts地图,其没有这部分行政区的数据,需要在第三方购买数据,其提供的是shp文件 主文件:counties.shp 索引文件:c ...
- 最新版Kali Linux虚拟机安装Open-vm-tools替代VMware tools
自从Kali 2.0发布之后,会经常遇到安装vmware tools无法成功,或者提示安装成功了但是仍旧无法进行文件拖拽.复制和剪切的问题. 今天给新电脑装系统,重新下载了最新版,Kali 2017. ...
- python学习第3天
03 int 十进制与二进制之间的转换04 bool 05 str python中凡是用引号引起来的都是字符串 1,存储相对少量的数据. 2,描述信息. 1,bool str int 三者之间的转换 ...
- 借助dubbo-admin来管理你的服务
1. Github上下载最新的dubbo源码包并解压 2. 修改配置信息(打开 dubbo-admin/src/main/webapp/WEB-INF下的dubbo.properties,修 ...
- python的生成器(斐波拉契数列(Fibonacci))
代码: 函数版本: #斐波拉契数列(Fibonacci) def fib(max): n=0 a,b=0,1 while n < max: a,b = b,a+b n = n+1 return ...