[SHOI 2012] 魔法树
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=2836
[算法]
树链剖分
时间复杂度 : O(NlogN ^ 2)
[代码]
#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010
typedef long long LL; struct edge
{
int to , nxt;
} e[MAXN << ]; int n , tot , timer;
int head[MAXN] , size[MAXN] , son[MAXN] , fa[MAXN] , dfn[MAXN] , depth[MAXN] , top[MAXN]; template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); }
template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
struct Segment_Tree
{
struct Node
{
int l , r;
LL sum , tag;
} Tree[MAXN << ];
inline void build(int index , int l , int r)
{
Tree[index].l = l;
Tree[index].r = r;
Tree[index].tag = Tree[index].sum = ;
if (l == r) return;
int mid = (l + r) >> ;
build(index << , l , mid);
build(index << | , mid + , r);
}
inline void pushdown(int index)
{
int l = Tree[index].l , r = Tree[index].r;
int mid = (l + r) >> ;
Tree[index << ].sum += (mid - l + ) * Tree[index].tag;
Tree[index << | ].sum += (r - mid) * Tree[index].tag;
Tree[index << ].tag += Tree[index].tag;
Tree[index << | ].tag += Tree[index].tag;
Tree[index].tag = ;
}
inline void update(int index)
{
Tree[index].sum = Tree[index << ].sum + Tree[index << | ].sum;
}
inline void modify(int index , int l , int r , LL value)
{
if (Tree[index].l == l && Tree[index].r == r)
{
Tree[index].sum += value * (r - l + );
Tree[index].tag += value;
return;
}
pushdown(index);
int mid = (Tree[index].l + Tree[index].r) >> ;
if (mid >= r) modify(index << , l , r , value);
else if (mid + <= l) modify(index << | , l , r , value);
else
{
modify(index << , l , mid , value);
modify(index << | , mid + , r , value);
}
update(index);
}
inline LL query(int index , int l , int r)
{
if (Tree[index].l == l && Tree[index].r == r) return Tree[index].sum;
pushdown(index);
int mid = (Tree[index].l + Tree[index].r) >> ;
if (mid >= r) return query(index << , l , r);
else if (mid + <= l) return query(index << | , l , r);
else return query(index << , l , mid) + query(index << | , mid + , r);
}
} SGT;
inline void addedge(int u , int v)
{
++tot;
e[tot] = (edge){v , head[u]};
head[u] = tot;
}
inline void dfs1(int u)
{
son[u] = -;
size[u] = ;
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to;
if (v == fa[u]) continue;
fa[v] = u;
depth[v] = depth[u] + ;
dfs1(v);
size[u] += size[v];
if (son[u] == - || size[v] > size[son[u]]) son[u] = v;
}
}
inline void dfs2(int u , int tp)
{
dfn[u] = ++timer;
top[u] = tp;
if (son[u] != -) dfs2(son[u] , tp);
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to;
if (v == fa[u] || v == son[u]) continue;
dfs2(v , v);
}
}
inline void modify(int u , int v , LL d)
{
int tu = top[u] , tv = top[v];
while (tu != tv)
{
if (depth[tu] > depth[tv])
{
swap(u , v);
swap(tu , tv);
}
SGT.modify( , dfn[tv] , dfn[v] , d);
v = fa[tv]; tv = top[v];
}
if (depth[u] > depth[v]) swap(u , v);
SGT.modify(, dfn[u] , dfn[v] , d);
} int main()
{ scanf("%d" , &n);
for (int i = ; i < n; i++)
{
int u , v;
scanf("%d%d" , &u , &v);
addedge(u , v);
fa[v] = u;
}
dfs1();
dfs2( , );
SGT.build( , , n);
int q;
scanf("%d" , &q);
while (q--)
{
char op[];
scanf("%s" , &op);
if (op[] == 'A')
{
int u , v;
LL d;
scanf("%d%d%lld" , &u , &v , &d);
modify(u , v , d);
} else
{
int u;
scanf("%d" , &u);
printf("%lld\n" , SGT.query( , dfn[u] , dfn[u] + size[u] - ));
}
} return ;
}
[SHOI 2012] 魔法树的更多相关文章
- 洛谷 3833 SHOI 2012 魔法树
[题解] 树链剖分模板题.. #include<cstdio> #include<algorithm> #include<queue> #define N 5000 ...
- noip模拟赛(一)魔法树
魔法树 (mahou.pas/c/cpp) [问题描述] 魔法使moreD在研究一棵魔法树. 魔法树顾名思义,这货是一棵树,奇葩的是魔法树上的每一条边都拥有一个魔法属性,如果不那么奇葩就不是moreD ...
- shoi 魔法树
Harry Potter新学了一种魔法:可以改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的新法术.这棵果树共有N个节点,其中节点0是根节点,每个节点u的父亲记为fa[u],保证有fa ...
- [bzoj2836] 魔法树
俩操作:增加路径上的点的权值.查询子树的权值和. 想了想似乎只能树链剖分了..好久没写链剖+数据结构了TAT 一开始没开LL炸了一发(明明有想到的..我果然是傻逼= = #include<cst ...
- P3833 [SHOI2012]魔法树
思路 树剖板子 注意给出点的编号是从零开始的 代码 #include <cstdio> #include <algorithm> #include <cstring> ...
- 解题:SHOI 2012 回家的路
题面 完了,做的时候已经想不起来分层图这个东西了QAQ 对于这种“多种”路径加中转站的题,还有那种有若干次“特殊能力”的题,都可以考虑用分层图来做 显然只需要记录所有的中转站+起点终点,然后拆出横竖两 ...
- [洛谷P3833][SHOI2012]魔法树
题目大意:给一棵树,路径加,子树求和 题解:树剖 卡点:无 C++ Code: #include <cstdio> #include <iostream> #define ma ...
- 【树链剖分】【dfs序】【线段树】bzoj2836 魔法树
这道题告诉我们:树链剖分的重标号就是dfs序. #include<cstdio> #include<algorithm> using namespace std; #defin ...
- 树链剖分【洛谷P3833】 [SHOI2012]魔法树
P3833 [SHOI2012]魔法树 题目描述 Harry Potter 新学了一种魔法:可以让改变树上的果子个数.满心欢喜的他找到了一个巨大的果树,来试验他的新法术. 这棵果树共有N个节点,其中节 ...
随机推荐
- PSO(Thepopularity-similarity-oplimization) modol
PSO(Thepopularity-similarity-oplimization) modol 在这篇文章里,我们试图将社交关系构成的网络结构从纷繁复杂的具体场景.细节条件中剥离出来,单单从个体间连 ...
- Oracle 12c安装报错Installation failed to access the temporary location(无法访问临时位置)
报错如图 1.先检查当前windows账户用户名是否为全英文,没有就新建一个,大多数用户败在这一步,而官方也没有解释 如何新建:开始-->控制面板-->用户账户和家庭安全-->用户账 ...
- avi视频文件提取与合并
最近在做一个avi视频文件的提取与合并,花了几天熟悉avi文件格式.制作了一个提取与合并的动态库,不过仅限于提取视频,视频的合并还没添加一些额外判断,可能导致不同分辨率的视频文件合成后不能播放.欢迎大 ...
- Jetty插件实现热部署(开发时修改文件自动重启Jetty)
在pom.xml文件中配置Jetty插件的参数:scanIntervalSeconds <plugin> <groupId>org.mortbay.jetty</grou ...
- win7安装ANT
点击进入ant官网,找到下载选项. 选择下载安装文件.其余的源文件和手册的下载步骤完全相同. 可以下载官网上对应系统的最新版本.也可以在old ant 版本中选择自己需要的版本.笔者需要ant ...
- jdk与jre安装之后的名字
jdk与jre安装之后的名字 jdk与jre的区别:https://blog.csdn.net/qq_33642117/article/details/52143824 jdk安装之后的名字: Jav ...
- [LeetCode][Java] Container With Most Water
题目: Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, a ...
- 吃我一记咸鱼突刺——使用板载RTC定时开机
前言 原创文章,转载引用务必注明链接.水平有限,欢迎指正. 2016年3月30日 Lemuntu(Base On Jessie) 3.10.37 原载于Lemaker论坛.汇总于此. 看ATC2603 ...
- 多重继承下的virtual functions
有如下图所示的继承关系: 有如下代码示例: 在早期的未符合c++标准的的编译器上是会报错的,因为对于clone()函数来说,编译器不知道怎么处理处理.但是时至今日c ...
- WCF 内存入口检查失败 Memory gates checking failed
在做JC系统时,出现这样的错误: 出现该错误信息的原因是因为WCF服务激活之前,系统应该具有的最小内存量不足config文件中设置的百分比.我是在本机调试的时候出现的. 解决方法: 关闭 ...