题目大意: 在给定带权值节点的树上从1开始不回头走到某个底端点后得到所有经过的点的权值后,这些点权值修改为0,到达底部后重新回到1,继续走,问走k次,最多能得到多少权值之和 这其实就是相当于每一次都走权值最大的那一条路径,进行贪心k次 首先先来想想树链剖分的时候的思想: 重儿子表示这个儿子对应的子树的节点数最多,那么每次访问都优先访问重儿子 这道题里面我们进行一下转化,如果当前儿子能走出一条最长的路径,我们就令其为重儿子,那么很容易想到,到达父亲时,如果选择重儿子,那么之前到达 父亲所得的权值一…
Stability Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)Total Submission(s): 1347    Accepted Submission(s): 319 Problem Description Given an undirected connected graph G with n nodes and m edges, with possibly r…
题意及博客 树链剖分分为2步,第一次求出深度,重儿子,第二次求出重链,用到了启发式的思想,即对于比较重的儿子,尽量去完整的维护它.类似于我们去合并两个堆,明显把小的堆逐个插入大的堆中会比大的往小的插更优,而这可以达到均摊O(logn)的效果.对于这个题,类似选重儿子, 我们每次尽量选择最长的路径,选出前m个就可以了. 代码: #include <bits/stdc++.h> #define LL long long using namespace std; const int maxn = 1…
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5044 题目大意:修改链上点,修改链上的边.查询所有点,查询所有边. 解题思路: 2014上海网赛的变态树链剖分模板题.将以往树链剖分的点&边修改和查询合在一起之后,难度上去不少. 第一个卡人点是读入优化. 第二个卡人点是树状数组.由于要查询所有点,如果使用线段树,每次都要扫到底层才能取出点值,必T无疑. 然后使用树状数组之后,树链剖分的点/边修改写法有些变动. 点查询变化不大. 边查询只要查询一下…
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3966 题目大意:营地的分布成树型.每个营地都有一些人,每次修改修改一条链上的所有营地的人数,每次查询单个点. 解题思路: 树链剖分基础题. 维护一个sum. 注意轻链修改时,点修改和边修改的不同. 由于树的结构与线段树点的顺序不太相同,因此需要做一个映射数组rank.故在线段树Build的时候,权值是camp[rank[l]],rank这步的映射在dfs2的时候完成,rank[w[u]]=u; Qu…
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5458 给你n个点,m条边,q个操作,操作1是删边,操作2是问u到v之间的割边有多少条. 这题要倒着做才容易,倒着加边. 因为这题最后保证所有的点一定连通,所以可以构建一棵树,树链剖分一下.要是u到v之间只有一条边,那便是一条割边.而加边的话,就是将u到v之间的边权都+1,边权等于1的话是桥,大于1的话就不是了.所以我们初始化树的时候,可以将边权初始化为1,加边操作将边权赋值为0.求u到v的割边个数的…
题意:给一棵树,两种操作: ADD1: 给u-v路径上所有点加上值k, ADD2:给u-v路径上所有边加上k,初始值都为0,问最后每个点和每条边的值,输出. 解法:树链剖分可做,剖出来如果直接用线段树来区间更新的话会TLE,所以要换一种姿势,有一种树链剖分的经典姿势就是看做树状数组一样,每次加值的时候,比如u->v之间加一个值k,那么在u处+k,v+1处-k即可,然后扫一遍,每次把当前位置要做的操作做完,此时总共加的值就是当前处的值,扫一遍的时候维护的是前缀的和,也就是两个ans不清零. 这题卡…
链接:https://vjudge.net/problem/HDU-3966 题意: Our protagonist is the handsome human prince Aragorn comes from The Lord of the Rings. One day Aragorn finds a lot of enemies who want to invade his kingdom. As Aragorn knows, the enemy has N camps out of hi…
题意: 给出一棵树,每个顶点上有一个权值. 操作:选择一条路径,并将路径上所有的点的权值同时加或减某个数. 查询:某个点的当前权值 分析: 树链剖分完毕后,就是简单的线段树区间更新. 提交的时候注意要要加一句扩栈的代码,用C++提交. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; void read(int& x) { x = ; char c = '…
wls 有三棵树,树上每个节点都有一个值 ai,现在有 2 种操作: 将一条链上的所有节点的值开根号向下取整: 求一条链上值的和: 链的定义是两点之间的最短路. Input 第一行两个数 n, q 分别代表树上点的数量和操作数量. 第二行 n 个整数,第 i 个数代表第 i 个点的值 ai. 接下来 n − 1 行, 每行两个整数 u, v 代表 u,v 之间有一条边.数据保证点两两联通. 接下来 q 行,每行有个整数 op, u, v,op = 0 表示将 u, v 这条链上所有的点的值开根号…