【BZOJ-2836】魔法树 树链剖分
2836: 魔法树
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 323 Solved: 129
[Submit][Status][Discuss]
Description
.jpg)
Input
.jpg)
Output
.jpg)
Sample Input
0 1
1 2
2 3
4
Add 1 3 1
Query 0
Query 1
Query 2
Sample Output
3
2
HINT
Source
Solution
树链修改,子树查询,可以直接树链剖分搞定
注意sum和tag要开longlong
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define INF 0x7fffffff
#define MAXN 100010
#define MAXM 100010
#define LL long long
int N,Q;
struct EdgeNode{int next,to;}edge[MAXN<<];
int cnt=,head[MAXN];
inline void AddEdge(int u,int v) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v;}
inline void InsertEdge(int u,int v) {AddEdge(u,v); AddEdge(v,u);}
namespace SegmentTree
{
struct SegmentTreeNode{int l,r,size; LL sum,tag;}tree[MAXN<<];
#define ls now<<1
#define rs now<<1|1
inline void Update(int now) {tree[now].sum=tree[ls].sum+tree[rs].sum;}
inline void PushDown(int now)
{
if (!tree[now].tag || tree[now].l==tree[now].r) return;
tree[ls].sum+=(LL)tree[ls].size*tree[now].tag; tree[ls].tag+=tree[now].tag;
tree[rs].sum+=(LL)tree[rs].size*tree[now].tag; tree[rs].tag+=tree[now].tag;
tree[now].tag=;
}
inline void BuildTree(int now,int l,int r)
{
tree[now].l=l; tree[now].r=r; tree[now].size=r-l+;
if (l==r) return;
int mid=(l+r)>>;
BuildTree(ls,l,mid); BuildTree(rs,mid+,r);
Update(now);
}
inline void Change(int now,int L,int R,int D)
{
int l=tree[now].l,r=tree[now].r;
if (L<=l && R>=r) {tree[now].tag+=D; tree[now].sum+=(LL)tree[now].size*D; return;}
PushDown(now);
int mid=(l+r)>>;
if (L<=mid) Change(ls,L,R,D);
if (R>mid) Change(rs,L,R,D);
Update(now);
}
inline LL Query(int now,int L,int R)
{
int l=tree[now].l,r=tree[now].r;
if (L<=l && R>=r) return tree[now].sum;
PushDown(now);
int mid=(l+r)>>; LL re=;
if (L<=mid) re+=Query(ls,L,R);
if (R>mid) re+=Query(rs,L,R);
return re;
}
}
namespace TreePartition
{
int fa[MAXN],size[MAXN],son[MAXN],deep[MAXN],pl[MAXN],dfn,pr[MAXN],pre[MAXN],top[MAXN];
inline void DFS_1(int now)
{
size[now]=;
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].to!=fa[now])
{
deep[edge[i].to]=deep[now]+;
fa[edge[i].to]=now;
DFS_1(edge[i].to);
size[now]+=size[edge[i].to];
if (size[son[now]]<size[edge[i].to]) son[now]=edge[i].to;
}
}
inline void DFS_2(int now,int chain)
{
top[now]=chain; pl[now]=++dfn; pre[dfn]=now;
if (son[now]) DFS_2(son[now],chain);
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].to!=fa[now] && edge[i].to!=son[now])
DFS_2(edge[i].to,edge[i].to);
pr[now]=dfn;
}
inline void Change(int x,int y,int D)
{
while (top[x]!=top[y])
{
if (deep[top[x]]<deep[top[y]]) swap(x,y);
SegmentTree::Change(,pl[top[x]],pl[x],D);
x=fa[top[x]];
}
if (deep[x]>deep[y]) swap(x,y);
SegmentTree::Change(,pl[x],pl[y],D);
}
inline void Query(int x) {printf("%lld\n",SegmentTree::Query(,pl[x],pr[x]));}
}
int main()
{
N=read();
for (int x,y,i=; i<=N-; i++) x=read()+,y=read()+,InsertEdge(x,y);
TreePartition::DFS_1(); TreePartition::DFS_2(,);
SegmentTree::BuildTree(,,N);
Q=read();
while (Q--)
{
char opt[]; scanf("%s",opt); int u,v,D;
switch (opt[])
{
case 'A': u=read()+,v=read()+,D=read(); TreePartition::Change(u,v,D); break;
case 'Q': u=read()+; TreePartition::Query(u); break;
}
}
return ;
}
又无故RE了一次
【BZOJ-2836】魔法树 树链剖分的更多相关文章
- bzoj 2836 魔法树 —— 树链剖分
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2836 树链剖分裸题: 写码五分钟,调码两小时,RE不断,狂交二十五遍,终于找到一处小细节—— ...
- 线段树&数链剖分
傻逼线段树,傻逼数剖 线段树 定义: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点在若干条线段中出现 ...
- bzoj 3252: 攻略 -- 长链剖分+贪心
3252: 攻略 Time Limit: 10 Sec Memory Limit: 128 MB Description 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神 ...
- bzoj 3252 攻略 长链剖分思想+贪心
攻略 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 889 Solved: 423[Submit][Status][Discuss] Descrip ...
- bzoj 2836 魔法树——树链剖分
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2836 树剖裸题.然而WA.RE了好久…… 原来是跳 top 的那个地方! top 不相等的时 ...
- BZOJ 2836: 魔法树 (树链剖分+线段树)
板题-记得开longlong #include <cstdio> #include <cctype> #include <cstring> #include < ...
- BZOJ 2836 魔法树 链剖裸题~~
正好练练熟练度..(刷水题谋财害命QAQ) #include<cstdio> #include<iostream> #define ll long long #define R ...
- [LOJ3014][JOI 2019 Final]独特的城市——树的直径+长链剖分
题目链接: [JOI 2019 Final]独特的城市 对于每个点,它的答案最大就是与它距离最远的点的距离. 而如果与它距离为$x$的点有大于等于两个,那么与它距离小于等于$x$的点都不会被计入答案. ...
- UOJ#30/Codeforces 487E Tourists 点双连通分量,Tarjan,圆方树,树链剖分,线段树
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ30.html 题目传送门 - UOJ#30 题意 uoj写的很简洁.清晰,这里就不抄一遍了. 题解 首先建 ...
- BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP
题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...
随机推荐
- ItemIndex
ItemIndex一般是列表的一个属性,比如TCombobox和TListBox都有,表示当前选中的项(Item)的下标(Index),如果没有选中,那它是-1,所以一般判断TCombox或TList ...
- 【WPF】TextBox样式重写注意事项
1.普通控件重写需要添加一行 <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="C ...
- XML Data Type Methods(一)
XML Data Type Methods(一) /*XML Data Type Methods: 1.The query('XQuery') method retrieves(vt.检索,重新得到) ...
- jQuery使用.on()无法绑定hover
发现好像没有hover这个事件,jQuery的hover事件是一个封装,hover算不得一个事件.他只是将mouseover和mouseout合并了用mouseover和mouseout两个配合效果好 ...
- How do I list the files in a directory?
原文地址:How do I list the files in a directory? You want a list of all the files, or all the files matc ...
- 为什么Javascript中的基本类型能调用方法?
我们从一道笔试题说起: var str = 'string'; str.pro = 'hello'; console.log(str.pro + 'world'); 输出啥?要理解这个问题,我们得从头 ...
- 基于DDD的.NET开发框架 - ABP仓储实现
返回ABP系列 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boilerplate是一个用最佳实践和流行技术开发现代WEB应 ...
- [codeforces 519E]E. A and B and Lecture Rooms(树上倍增)
题目:http://codeforces.com/problemset/problem/519/E 题意:给你一个n个点的树,有m个询问(x,y),对于每个询问回答树上有多少个点和x,y点的距离相等 ...
- C语言字符串与数字相互转换
在C/C++语言中没有专门的字符串变量,通常用字符数组来存放字符串.字符串是以“\0”作为结束符.C/C++提供了丰富的字符串处理函数,下面列出了几个最常用的函数. ● 字符串输出函数puts. ● ...
- centos 7 安装mysql
# wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm # rpm -ivh mysql-community- ...