题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2836

树链剖分裸题;

写码五分钟,调码两小时,RE不断,狂交二十五遍,终于找到一处小细节——易错点!

就是跳 top 时,不是按 dep[x] < dep[y] 交换 x,y,而要按 dep[top[x]] < dep[top[y]] 交换 x,y,否则就跳不到 lca 了!

经验++。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mid ((l+r)>>1)
#define ls (x<<1)
#define rs (x<<1|1)
using namespace std;
typedef long long ll;
int const xn=;
int n,fa[xn],hd[xn],ct,nxt[xn],to[xn],dfn[xn],tim,siz[xn],son[xn],top[xn],dep[xn];
ll sum[xn<<],lzy[xn<<];
char ch[];
int rd()
{
int ret=,f=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=; ch=getchar();}
while(ch>=''&&ch<='')ret=(ret<<)+(ret<<)+ch-'',ch=getchar();
return f?ret:-ret;
}
void add(int x,int y){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct;}
void dfs(int x)
{
siz[x]=; dep[x]=dep[fa[x]]+;
for(int i=hd[x],u;i;i=nxt[i])
{
dfs(u=to[i]);
if(siz[u]>siz[son[x]])son[x]=u;
siz[x]+=siz[u];
}
}
void dfs2(int x)
{
dfn[x]=++tim;
if(son[x])top[son[x]]=top[x],dfs2(son[x]);
for(int i=hd[x],u;i;i=nxt[i])
{
if((u=to[i])==son[x])continue;
top[u]=u; dfs2(u);
}
// ed[x]=tim;
}
void pushdown(int x,int l,int r)
{
if(!lzy[x])return;
sum[ls]+=lzy[x]*(mid-l+); lzy[ls]+=lzy[x];
sum[rs]+=lzy[x]*(r-mid); lzy[rs]+=lzy[x];
lzy[x]=;
}
void update(int x,int l,int r,int L,int R,int k)
{
if(l>=L&&r<=R){sum[x]+=(ll)k*(r-l+); lzy[x]+=k; return;}
pushdown(x,l,r);
if(mid>=L)update(ls,l,mid,L,R,k);
if(mid<R)update(rs,mid+,r,L,R,k);
sum[x]=sum[ls]+sum[rs];
}
ll query(int x,int l,int r,int L,int R)
{
if(l>=L&&r<=R)return sum[x];
pushdown(x,l,r); ll ret=;
if(mid>=L)ret+=query(ls,l,mid,L,R);
if(mid<R)ret+=query(rs,mid+,r,L,R);
return ret;
}
void add(int x,int y,int d)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);//!!!!!
update(,,n,dfn[top[x]],dfn[x],d); x=fa[top[x]];
}
if(dep[x]<dep[y])swap(x,y);
update(,,n,dfn[y],dfn[x],d);
}
int main()
{
n=rd();
for(int i=,x,y;i<n;i++)
{
x=rd()+; y=rd()+;
fa[y]=x; add(x,y);
}
dfs(); top[]=; dfs2();
int q=rd();
for(int i=,u,v,d;i<=q;i++)
{
scanf("%s",ch);
if(ch[]=='A')
{
u=rd()+; v=rd()+; d=rd();
add(u,v,d);
}
else u=rd()+,printf("%lld\n",query(,,n,dfn[u],dfn[u]+siz[u]-));
}
return ;
}

bzoj 2836 魔法树 —— 树链剖分的更多相关文章

  1. 线段树&数链剖分

    傻逼线段树,傻逼数剖 线段树 定义: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点在若干条线段中出现 ...

  2. bzoj 3252: 攻略 -- 长链剖分+贪心

    3252: 攻略 Time Limit: 10 Sec  Memory Limit: 128 MB Description 题目简述:树版[k取方格数]   众所周知,桂木桂马是攻略之神,开启攻略之神 ...

  3. bzoj 3252 攻略 长链剖分思想+贪心

    攻略 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 889  Solved: 423[Submit][Status][Discuss] Descrip ...

  4. bzoj 2836 魔法树——树链剖分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2836 树剖裸题.然而WA.RE了好久…… 原来是跳 top 的那个地方! top 不相等的时 ...

  5. BZOJ 2836: 魔法树 (树链剖分+线段树)

    板题-记得开longlong #include <cstdio> #include <cctype> #include <cstring> #include < ...

  6. BZOJ 2836 魔法树 链剖裸题~~

    正好练练熟练度..(刷水题谋财害命QAQ) #include<cstdio> #include<iostream> #define ll long long #define R ...

  7. [LOJ3014][JOI 2019 Final]独特的城市——树的直径+长链剖分

    题目链接: [JOI 2019 Final]独特的城市 对于每个点,它的答案最大就是与它距离最远的点的距离. 而如果与它距离为$x$的点有大于等于两个,那么与它距离小于等于$x$的点都不会被计入答案. ...

  8. UOJ#30/Codeforces 487E Tourists 点双连通分量,Tarjan,圆方树,树链剖分,线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ30.html 题目传送门 - UOJ#30 题意 uoj写的很简洁.清晰,这里就不抄一遍了. 题解 首先建 ...

  9. BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP

    题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...

随机推荐

  1. 教妹学 Java:大有可为的集合

    00.故事的起源 “二哥,上一篇<泛型>的反响效果怎么样啊?”三妹对她提议的<教妹学 Java>专栏很是关心. “有人评论说,‘二哥你敲代码都敲出幻想了啊.’” “呵呵,这句话 ...

  2. [TJOI2019]唱、跳、rap和篮球_生成函数_容斥原理_ntt

    [TJOI2019]唱.跳.rap和篮球 这么多人过没人写题解啊 那我就随便说说了嗷 这题第一步挺套路的,就是题目要求不能存在balabala的时候考虑正难则反,要求必须存在的方案数然后用总数减,往往 ...

  3. java集合系列之ArrayList源码分析

    java集合系列之ArrayList源码分析(基于jdk1.8) ArrayList简介 ArrayList时List接口的一个非常重要的实现子类,它的底层是通过动态数组实现的,因此它具备查询速度快, ...

  4. 新建JRapid项目(idea创建maven多模块项目)

    1.第一步,新建项目(Create New Project) 2.parent项目,不勾选“Crate from archetype”,直接单击“Next”. 3.groupid填写com.codin ...

  5. 关于时间,日期,星期,月份的算法(Java中Calendar的使用方法)

    原文:http://www.open-open.com/code/view/1446195787257 package cn.outofmemory.codes.Date; import java.u ...

  6. 高速清除winXP系统中explorer.exe病毒

    关于这个explorer.exe病毒.是眼下xp最为常见的一个病毒,会大量的消耗系统资源,造成电脑特别的卡顿. 1.关闭还原(假设没有,则跳过),为的是防止我们改动后,还原之后又回来了. 2.打开注冊 ...

  7. 【LeetCode-面试算法经典-Java实现】【079-Word Search(单词搜索)】

    [079-Word Search(单词搜索)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given a 2D board and a word, find if ...

  8. C#语言 数组

  9. Android学习笔记(十)——使用意图链接活动

    使用意图链接活动 1.新建一个名为"UsingIntent"的项目,右击src目录下的包名,选择New-->Class选项.并将新的类文件名称命名为"SecondA ...

  10. EasyBCD在windows7基础上安装Ubuntu 14.04双系统详

    把下载好的ubuntu安装包放在C盘根文件夹下,利用Daemon Tools 将安装包下casper文件夹的vmlinuz.efi和initrd.lz复制到C盘根文件夹下,紧接着打开easybcd,在 ...