[树链剖分]BZOJ3589动态树
题目描述
小明希望你求出几条树枝上的果子数. 一条树枝其实就是一个从某个节点到根的路径的一段. 每次小明会选定一些树枝, 让你求出在这些树枝上的节点的果子数的和. 注意, 树枝之间可能会重合, 这时重合的部分的节点的果子只要算一次.
输入
如果是1, 表示这个事件是事件1. 这行接下来一个整数K(1<=K<=5), 表示这次询问涉及K个树枝. 接下来K对整数u_k, v_k, 每个树枝从节点u_k到节点v_k. 由于果子数可能非常多, 请输出这个数模2^31的结果.
输出
对于每个事件1, 输出询问的果子数.
样例输入
5
1 2
2 3
2 4
1 5
3
0 1 1
0 2 3
1 2 3 1 1 4
样例输出
13
解析
因为是动态的,所以放弃倍增LCA,考虑树链剖分(为什么做树的问题时我脑子里只有这两个东西?)。
对于事件0,直接在dfs序上区间修改x及其子树,即从x到x+siz[x]-1全部加k。
对于事件1,先对于每条链,求出它在dfs序上对应的区间,然后将这些区间合并起来,最后查询即可
合并区间的时候,先按照左端点由小到大给区间排序,然后从小到大遍历,若当前区间的右端点在下一个区间左端点的右边就可以把两个区间合并起来。
还有就是模2^31的问题,找Master Yi问了一下,好像是可以不管炸int的,只需要在最后&一下2^31-1即可。
代码如下
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=;
const int inf=;
struct node{int l,r;}q[maxn];
int en,mk[maxn<<],sum[maxn<<];
int n,Q,id,info[maxn],nx[maxn<<],v[maxn<<];
int fa[maxn],dep[maxn],dfn[maxn],siz[maxn],son[maxn],top[maxn];
bool cmp(node a,node b){return a.l==b.l?a.r<b.r:a.l<b.l;}
void add(int u1,int v1){nx[++id]=info[u1];info[u1]=id;v[id]=v1;}
void dfs1(int x,int f)
{
dep[x]=dep[fa[x]=f]+(siz[x]=);
for(int i=info[x];i;i=nx[i])if(v[i]!=f)
{
dfs1(v[i],x);siz[x]+=siz[v[i]];
if(siz[v[i]]>siz[son[x]])son[x]=v[i];
}
}
void dfs2(int x,int f)
{
dfn[x]=++id;top[x]=f;if(son[x])dfs2(son[x],f);
for(int i=info[x];i;i=nx[i])if(v[i]!=fa[x]&&v[i]!=son[x])dfs2(v[i],v[i]);
}
void pushdown(int id,int l,int r)
{
int mid=(l+r)/;
mk[id*]+=mk[id];mk[id*+]+=mk[id];
sum[id*]+=(mid-l+)*mk[id];sum[id*+]+=(r-mid)*mk[id];mk[id]=;
}
void fix(int id,int l,int r,int l1,int r1,int k)
{
if(r1<l||r<l1)return;
if(l1<=l&&r<=r1){sum[id]+=k*(r-l+);mk[id]+=k;return;}
pushdown(id,l,r);int mid=(l+r)/;
fix(id*,l,mid,l1,r1,k);fix(id*+,mid+,r,l1,r1,k);sum[id]=sum[id*]+sum[id*+];
}
int que(int id,int l,int r,int l1,int r1)
{
if(r1<l||r<l1)return ;
if(l1<=l&&r<=r1)return sum[id];
pushdown(id,l,r);int mid=(l+r)/;
return que(id*,l,mid,l1,r1)+que(id*+,mid+,r,l1,r1);
}
int main()
{
scanf("%d",&n);
for(int i=,u1,v1;i<n;i++)scanf("%d%d",&u1,&v1),add(u1,v1),add(v1,u1);
id=;dfs1(,);dfs2(,);id=;
scanf("%d",&Q);
for(int i=,ord,x,k;i<=Q;i++)
{
scanf("%d",&ord);
if(ord==)scanf("%d%d",&x,&k),fix(,,n,dfn[x],dfn[x]+siz[x]-,k);
if(ord==)
{
scanf("%d",&k);en=;
for(int i=,a,b;i<=k;i++)
{
scanf("%d%d",&a,&b);
if(dep[b]>dep[a])swap(a,b);
while(top[a]!=top[b])q[++en]=(node){dfn[top[a]],dfn[a]},a=fa[top[a]];
q[++en]=(node){dfn[b],dfn[a]};
}
sort(q+,q++en,cmp);
int ans=;
for(int i=,l,r;i<=en;i++)
{
l=q[i].l,r=q[i].r;
while(q[i+].l<=r&&i+<=en)r=max(q[i+].r,r),i++;
ans+=que(,,n,l,r);
}
printf("%d\n",ans&inf);
}
}
}
[树链剖分]BZOJ3589动态树的更多相关文章
- Bzoj 2243: [SDOI2011]染色 树链剖分,LCT,动态树
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 5020 Solved: 1872[Submit][Status ...
- bzoj 4034 [HAOI2015] T2(树链剖分,线段树)
4034: [HAOI2015]T2 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1536 Solved: 508[Submit][Status] ...
- bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 10677 Solved: 4313[Submit ...
- poj 3237 Tree(树链剖分,线段树)
Tree Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 7268 Accepted: 1969 Description ...
- bzoj 3626 [LNOI2014]LCA(离线处理+树链剖分,线段树)
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1272 Solved: 451[Submit][Status ...
- bzoj 2243 [SDOI2011]染色(树链剖分,线段树)
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 4637 Solved: 1726[Submit][Status ...
- HDU 4366 Successor(树链剖分+zkw线段树+扫描线)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4366 [题目大意] 有一个公司,每个员工都有一个上司,所有的人呈树状关系,现在给出每个人的忠诚值和 ...
- 【BZOJ3531】旅行(树链剖分,线段树)
[BZOJ3531]旅行(树链剖分,线段树) 题面 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教 ...
- 【BZOJ5507】[GXOI/GZOI2019]旧词(树链剖分,线段树)
[BZOJ5507][GXOI/GZOI2019]旧词(树链剖分,线段树) 题面 BZOJ 洛谷 题解 如果\(k=1\)就是链并裸题了... 其实\(k>1\)发现还是可以用类似链并的思想,这 ...
随机推荐
- 【转载】C#中string类使用Remove方法来移除指定位置的字符
在C#的字符串操作过程中,有时候需要将字符串中指定位置的字符移除,此时就可能使用到字符串类string类中的Remove方法,此方法允许指定移除开始的开始的索引位置,以及移除的长度信息等,共有2个重载 ...
- 各种GAN的学习和总结
GAN: https://www.cnblogs.com/kk17/p/10046884.html WGAN: https://www.cnblogs.com/Allen-rg/p/10305125. ...
- day31-python之内置函数
1.udp多线程 import socketserver class MyServer(socketserver.BaseRequestHandler): def handle(self): prin ...
- jenkins报错 Upgrading Jenkins. Failed to update the default Update Site 'default'. Plugi
解决方案: jenkins\hudson.model.UpdateCenter.xml 文件, 将 url 中的 https://updates.jenkins.io/update-center.js ...
- SQL SERVER-修改实例的排序规则
系统库是无法直接修改的,只能修改用户数据库排序规则(要先解决依赖项.如表函数): ALTER DATABASE [xx] COLLATE Chinese_PRC_CI_AS 修改实例的排序规则,使用安 ...
- Mybatis,返回Map的时候,将Map内的Key转换为驼峰的命名
每次使用mybatis的时候,简单的连表查询,用Map接收的时候,都是像DB定义的字段一样,类似以下 student_name,student_id,没有转换为驼峰,但是又不能因为这一个定义一个jav ...
- c# 使用泛型集合List<T>
- log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment)的解决
报错:log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironme ...
- flutter入门开发的一些坑
flutter入门开发的一些坑 很久没写博客了,最近在准备物联网比赛,顺便抽出时间学习了一下flutter,花了近2周完成了一个查看博客博文的一个小的APPdemo,随便截了两张图,如下: 首页 博客 ...
- IDEA快速搭建WEB项目【记录篇】
这里用的都是市面上通用的技术,而每个公司都有自己的调用方式,可以根据实际情况与业务场景不同去进行变通 三层架构: 界面层(User Interface layer).业务逻辑层(Business Lo ...