题目描述

别忘了这是一棵动态树, 每时每刻都是动态的. 小明要求你在这棵树上维护两种事件
事件0:
这棵树长出了一些果子, 即某个子树中的每个节点都会长出K个果子.
事件1:

小明希望你求出几条树枝上的果子数. 一条树枝其实就是一个从某个节点到根的路径的一段. 每次小明会选定一些树枝, 让你求出在这些树枝上的节点的果子数的和. 注意, 树枝之间可能会重合, 这时重合的部分的节点的果子只要算一次.

输入

第一行一个整数n(1<=n<=200,000), 即节点数.
接下来n-1行, 每行两个数字u, v. 表示果子u和果子v之间有一条直接的边. 节点从1开始编号.
在接下来一个整数nQ(1<=nQ<=200,000), 表示事件.
最后nQ行, 每行开头要么是0, 要么是1.
如果是0, 表示这个事件是事件0. 这行接下来的2个整数u, delta表示以u为根的子树中的每个节点长出了delta个果子.

如果是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动态树的更多相关文章

  1. Bzoj 2243: [SDOI2011]染色 树链剖分,LCT,动态树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 5020  Solved: 1872[Submit][Status ...

  2. bzoj 4034 [HAOI2015] T2(树链剖分,线段树)

    4034: [HAOI2015]T2 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1536  Solved: 508[Submit][Status] ...

  3. bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)

    1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 10677  Solved: 4313[Submit ...

  4. poj 3237 Tree(树链剖分,线段树)

    Tree Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 7268   Accepted: 1969 Description ...

  5. bzoj 3626 [LNOI2014]LCA(离线处理+树链剖分,线段树)

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

  6. bzoj 2243 [SDOI2011]染色(树链剖分,线段树)

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 4637  Solved: 1726[Submit][Status ...

  7. HDU 4366 Successor(树链剖分+zkw线段树+扫描线)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4366 [题目大意] 有一个公司,每个员工都有一个上司,所有的人呈树状关系,现在给出每个人的忠诚值和 ...

  8. 【BZOJ3531】旅行(树链剖分,线段树)

    [BZOJ3531]旅行(树链剖分,线段树) 题面 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教 ...

  9. 【BZOJ5507】[GXOI/GZOI2019]旧词(树链剖分,线段树)

    [BZOJ5507][GXOI/GZOI2019]旧词(树链剖分,线段树) 题面 BZOJ 洛谷 题解 如果\(k=1\)就是链并裸题了... 其实\(k>1\)发现还是可以用类似链并的思想,这 ...

随机推荐

  1. OO第四单元(UML)单元总结

    OO第四单元(UML)单元总结 这是OO课程的第四个单元,也是最后一个单元.这个单元只有两次作业,相比前三个单元少一次作业.而且从内容上讲这个单元的作业目的以了解UML为主,所以相对前三个单元比较简单 ...

  2. PHP 中使用ajax时一些常见错误总结整理

    这篇文章主要介绍了PHP 中使用ajax时一些常见错误总结整理的相关资料,需要的朋友可以参考下 PHP作为后端时,前端js使用ajax技术进行相互信息传送时,经常会出错误,对于新手来说有些手足无措.总 ...

  3. js实现frame框架部分页面的刷新

    一.先来看一个简单的例子: 下面以三个页面分别命名为frame.html.top.html.bottom.html为例来具体说明如何做. frame.html 由上(top.html)下(bottom ...

  4. xcode 4 制作通用静态库

    参考:http://blog.csdn.net/pjk1129/article/details/7255163 最近在做Apple的IOS开发,有开发静态库的需求,本身IOS的开发,只允许静态库或者F ...

  5. 聊Java中的任务调度的实现方法及比较

    前言 任务调度是指基于给定时间点,给定时间间隔或者给定执行次数自动执行任务.本文由浅入深介绍四种任务调度的 Java 实现: Timer ScheduledExecutor 开源工具包 Quartz ...

  6. python(字典函数/操作)

    一.字典操作 1.往字典中添加键值对 dict["key"] = "value" stu = {"} stu["sex"] = & ...

  7. mysql遇到时区问题的坑(Java解决方案)

    最近项目遇到一个坑,就是server和db之间存在时区问题,本人的db是utc时间, 可以使用代码设置时区来解决,本人这里使用joda三方包,joda蛮好用的,具体用法这里不做详细描述. 先引入pom ...

  8. Andrew Ng机器学习 五:Regularized Linear Regression and Bias v.s. Variance

    背景:实现一个线性回归模型,根据这个模型去预测一个水库的水位变化而流出的水量. 加载数据集ex5.data1后,数据集分为三部分: 1,训练集(training set)X与y: 2,交叉验证集(cr ...

  9. substr()用法

    知识点链接:http://www.cplusplus.com/reference/string/string/substr/ 注意: std::string str2 = str.substr (po ...

  10. LG2664 树上游戏

    树上游戏 题目描述 lrb有一棵树,树的每个节点有个颜色.给一个长度为n的颜色序列,定义s(i,j) 为i 到j 的颜色数量.以及 $$sum_i=\sum_{j=1}^ns(i,j)$$ 现在他想让 ...