树链剖分【P3833】 [SHOI2012]魔法树
Description
Harry Potter 新学了一种魔法:可以让改变树上的果子个数。满心欢喜的他找到了一个巨大的果树,来试验他的新法术。
这棵果树共有N个节点,其中节点0是根节点,每个节点u的父亲记为fa[u],保证有fa[u] < u。初始时,这棵果树上的果子都被 Dumbledore 用魔法清除掉了,所以这个果树的每个节点上都没有果子(即0个果子)。
不幸的是,Harry 的法术学得不到位,只能对树上一段路径的节点上的果子个数统一增加一定的数量。也就是说,Harry 的魔法可以这样描述:
Add u v d
表示将点u和v之间的路径上的所有节点的果子个数都加上d。
接下来,为了方便检验 Harry 的魔法是否成功,你需要告诉他在释放魔法的过程中的一些有关果树的信息:
Query u
表示当前果树中,以点u为根的子树中,总共有多少个果子?
Input
第一行一个正整数N (1 ≤ N ≤ 100000),表示果树的节点总数,节点以0,1,…,N − 1标号,0一定代表根节点。
接下来N − 1行,每行两个整数a,b (0 ≤ a < b < N),表示a是b的父亲。
接下来是一个正整数Q(1 ≤ ? ≤ 100000),表示共有Q次操作。
后面跟着Q行,每行是以下两种中的一种:
- A u v d,表示将u到v的路径上的所有节点的果子数加上d;0 ≤ u,v <N,0 < d < 100000
 - Q u,表示询问以u为根的子树中的总果子数,注意是包括u本身的。
 Output
对于所有的Query操作,依次输出询问的答案,每行一个。答案可能会超过2^32 ,但不会超过10^15 。
刚刚学树剖练练手,一个树剖裸题,线段树不需要建树.
话说省选竟然会考模板题emm
PS:数组开大,开$long \ long $,还有记得用字符串读入,不要用单个字符。
代码
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
#define int long long
#define R register
#define ls o<<1
#define rs o<<1|1
#define N 200008
using namespace std;
inline void in(int &x)
{
    int f=1;x=0;char s=getchar();
    while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
    while(isdigit(s)){x=x*10+s-'0';s=getchar();}
    x*=f;
}
int n,head[N],tot,depth[N],size[N],son[N],dfn[N],fdfn[N],f[N];
struct cod{int u,v;}edge[N<<1];
int idx,m,top[N],tr[N<<2],tg[N<<2];
inline void add(int x,int y)
{
    edge[++tot].u=head[x];
    edge[tot].v=y;
    head[x]=tot;
}
void dfs1(int u,int fa)
{
    depth[u]=depth[fa]+1;size[u]=1;f[u]=fa;
    for(R int i=head[u];i;i=edge[i].u)
    {
        if(edge[i].v==fa)continue;
        dfs1(edge[i].v,u);
        size[u]+=size[edge[i].v];
        if(son[u]==-1 or size[son[u]]<size[edge[i].v])
            son[u]=edge[i].v;
    }
}
void dfs2(int u,int t)
{
    top[u]=t;dfn[u]=++idx;fdfn[idx]=u;
    if(son[u]==-1)return;
    dfs2(son[u],t);
    for(R int i=head[u];i;i=edge[i].u)
    {
        if(dfn[edge[i].v])continue;
        dfs2(edge[i].v,edge[i].v);
    }
}
inline void down(int o,int l,int r)
{
    if(tg[o])
    {
        int mid=(l+r)>>1;
        tg[ls]+=tg[o];tg[rs]+=tg[o];
        tr[ls]+=(mid-l+1)*tg[o];tr[rs]+=(r-mid)*tg[o];
        tg[o]=0;
    }
}
void change(int o,int l,int r,int x,int y,int z)
{
    if(x<=l and y>=r)
    {
        tr[o]+=(r-l+1)*z;
        tg[o]+=z;
        return;
    }
    down(o,l,r);
    int mid=(l+r)>>1;
    if(x<=mid)change(ls,l,mid,x,y,z);
    if(y>mid)change(rs,mid+1,r,x,y,z);
    tr[o]=tr[ls]+tr[rs];
}
int query(int o,int l,int r,int x,int y)
{
    if(x<=l and y>=r)return tr[o];
    down(o,l,r);
    int mid=(l+r)>>1,res=0;
    if(x<=mid)res+=query(ls,l,mid,x,y);
    if(y>mid)res+=query(rs,mid+1,r,x,y);
    return res;
}
inline void tchange(int x,int y,int z)
{
    int fx=top[x],fy=top[y];
    while(fx!=fy)
    {
        if(depth[fx]>depth[fy])
        {
            change(1,1,idx,dfn[fx],dfn[x],z);
            x=f[fx];
        }
        else
        {
            change(1,1,idx,dfn[fy],dfn[y],z);
            y=f[fy];
        }
        fx=top[x],fy=top[y];
    }
    if(dfn[x]>dfn[y])swap(x,y);
    change(1,1,idx,dfn[x],dfn[y],z);
}
signed main()
{
    in(n);memset(son,-1,sizeof son);
    for(R int i=1,x,y;i<n;i++)
    {
        in(x),in(y);
        x++,y++;
        add(x,y);add(y,x);
    }
    dfs1(1,0);dfs2(1,1);
    in(m);
    for(R int x,y,z;m;m--)
    {
        R char opt[8];
        scanf("%s",opt);
        switch(opt[0])
        {
            case 'A':in(x),in(y),in(z);x++;y++;tchange(x,y,z);break;
            case 'Q':in(x);x++;printf("%lld\n",query(1,1,n,dfn[x],dfn[x]+size[x]-1));break;
        }
    }
}
												
											树链剖分【P3833】 [SHOI2012]魔法树的更多相关文章
- 洛谷——P3833 [SHOI2012]魔法树
		
P3833 [SHOI2012]魔法树 题目背景 SHOI2012 D2T3 题目描述 Harry Potter 新学了一种魔法:可以让改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的 ...
 - 洛谷 P3833 [SHOI2012]魔法树
		
题目背景 SHOI2012 D2T3 题目描述 Harry Potter 新学了一种魔法:可以让改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的新法术. 这棵果树共有N个节点,其中节点 ...
 - P3833 [SHOI2012]魔法树
		
思路 树剖板子 注意给出点的编号是从零开始的 代码 #include <cstdio> #include <algorithm> #include <cstring> ...
 - [洛谷P3833][SHOI2012]魔法树
		
题目大意:给一棵树,路径加,子树求和 题解:树剖 卡点:无 C++ Code: #include <cstdio> #include <iostream> #define ma ...
 - P3833 [SHOI2012]魔法树 (树链剖分模板题)
		
题目链接:https://www.luogu.org/problem/P3833 题目大意:有一颗含有n个节点的树,初始时每个节点的值为0,有以下两种操作: 1.Add u v d表示将点u和v之间的 ...
 - 【树链剖分】【dfs序】【线段树】bzoj2836 魔法树
		
这道题告诉我们:树链剖分的重标号就是dfs序. #include<cstdio> #include<algorithm> using namespace std; #defin ...
 - 【SHOI2012】魔法树(树链剖分,线段树)
		
[SHOI2012]魔法树 题面 BZOJ上找不到这道题目 只有洛谷上有.. 所以粘贴洛谷的题面 题解 树链剖分之后直接维护线段树就可以了 树链剖分良心模板题 #include<iostream ...
 - BZOJ2863[SHOI2012]魔法树——树链剖分+线段树
		
题目描述 输入 输出 样例输入 4 0 1 1 2 2 3 4 Add 1 3 1 Query 0 Query 1 Query 2 样例输出 3 3 2 树链剖分模板题,路径修改子树查询,注意节点 ...
 - 【BZOJ-2836】魔法树       树链剖分
		
2836: 魔法树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 323 Solved: 129[Submit][Status][Discuss] ...
 - 树链剖分好(du)题(liu)选做
		
1.luogu P4315 月下"毛景树" 题目链接 前言: 这大概是本蒟蒻A掉的题里面码量最大的一道题了.我自认为码风比较紧凑,但还是写了175行. 从下午2点多调到晚上8点.中 ...
 
随机推荐
- 【APUE】Chapter8 Process Control
			
这章的内容比较多.按照小节序号来组织笔记的结构:再结合函数的示例带代码标注出来需要注意的地方. 下面的内容只是个人看书时思考内容的总结,并不能代替看书(毕竟APUE是一本大多数人公认的UNIX圣经). ...
 - Spring整合EhCache详解
			
一.EhCache介绍 EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认的CacheProvider.Ehcache是一种广泛使用的开 源Java分布 ...
 - mac虚拟机上(centos系统)怎样实现共享本机文件
			
首先加载vboxadditions,可以从https://download.virtualbox.org/virtualbox/下载,记得一定要跟virtualBox版本对应 然后打开virtualb ...
 - Linux查看端口被占用情形
			
查看某端口的占用情况: lsof -i:<端口号> 例如:lsof -i:8080 netstat -apn|grep <端口号> 例如: netstat -apn | gre ...
 - 五、SPR 单一职责
			
1.一个类具有什么职责,应该是站在他人的角度或者说是使用者的角度来定义.职责不是一件事,而是许多和职责相关的事组成的. 例如:一个快递员,除了送快递,还需要做分包.收款.那么快递员的职责是和快递相关的 ...
 - 如何修改root密码
			
默认情况下,每次登录ubuntu都会生成一个随机的root密码,如果想要修改, sudo passwd 然后输入密码,这个密码就作为root用户的密码
 - 用jQuery制作仿网易云课堂导航菜单效果
			
最近做项目,用到类似的效果. 效果图如下: 直接上代码: HTML: <!DOCTYPE html> <html lang="en"> <head&g ...
 - zoj3161 Damn Couples
			
不想打题面了,题面戳这里 这道题目的模型转换地有点猛.首先我们肯定需要让老板把那些不相邻的人的卡牌放在前面,这样他们就作废了.然后剩下的卡牌就都是相邻人之间的了.我们就可以把这个序列分成若干个联通块, ...
 - Codeforces 934.A A Compatible Pair
			
A. A Compatible Pair time limit per test 1 second memory limit per test 256 megabytes input standard ...
 - js函数形参和实参的区别
			
在<Javascript权威指南>中这样定义: 参数有形参(parameter)和实参(argument)的区别,形参相当于函数中定义的变量,实参是在运行时的函数调用时传入的参数. 说明白 ...