[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2888 [题目大意] 不断加边,问每个连通块的重心到其它点的距离和的和 [题解] 启发式合并LCT,通过维护等差数列的首项和公差 来实现保存子树内所有节点到这个节点的距离之和. [代码] #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const in…
挺好想的,最简单的方法是并查集启发式合并,加暴力跳父亲. 然而,这个代码量比较小,比较好写,所以我写了 LCT,更具挑战性. #include <cstdio> #include <algorithm> #define N 1000004 #define lson t[x].ch[0] #define rson t[x].ch[1] #define setIO(s) freopen(s".in","r",stdin) using namesp…
Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数表示 N个节点上的权值. 接下来 M行,每行包含两个整数x和 y,表示初始的时候,点x和点y 之间有一条无向边, 接下来 T行,每行描述一个操作,格式为"Q x y k"或者"L x y ",其含义见题目描述部分. Output 对于每一个第一类…
Description 给你一片森林, 支持两个操作: 查询$x$到$y$的$K$大值,  连接两棵树中的两个点 Solution 对每个节点$x$动态开权值线段树, 表示从$x$到根节点路径上权值出现的次数. 查询时差分即可: $sum[x]+sum[y]-sum[lca]-sum[f[lca]]$ 连边时需要启发式合并,将节点数小的接到节点数大的上去, 再遍历小的树, 并更新权值 我刚开始以为testcase是数据组数, TLE我好久,, Code #include<cstdio> #in…
思路: 主席树 搞树上的k大 x+y-lca(x,y)-fa(lca(x,y)) 按照size小树往大树上插 启发式合并 n*log^2n的 搞定~ //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define N 666666 const int inf=1000000000;char op[2]; int cases,n,m,…
题面 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切地说,你需要选择尽可能多的节点,满足大根堆的性质:对于任意两个点i,j,如果i在树上是j的祖先,那么v_i>v_j. 请计算可选的最多的点数,注意这些点不必形成这棵树的一个连通子树. 分析 由于点不需要相邻,此题其实是树上的LIS,从叶子节点向根节点形成LIS 考虑LIS的\(O(nlogn)\)算法中用到的数组,用multiset对每个节点维护这样一个数组,存储子…
Description 在Bytemountains有N座山峰,每座山峰有他的高度h_i.有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经过困难值小于等于x的路径所能到达的山峰中第k高的山峰,如果无解输出-1. Input 第一行三个数N,M,Q. 第二行N个数,第i个数为h_i 接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径. 接下来Q行,每行三个数v x k,表示一组询问. Output…
2888: 资源运输 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 63  Solved: 33[Submit][Status][Discuss] Description        小Y盯上了最近发行的即时战略游戏——ResourceTransport.但在前往通关之路的道路上,一个小游戏挡住了小Y的步伐.“国家的本质是生产与收集资源”是整款游戏的核心理念,这个小游戏也不例外.简单的说,用户需要管理一个国家,使其繁荣富强.        一个…
这道题目太神啦! 我们考虑他的每一次合并操作,为了维护两棵树合并后树的重心,我们只好一个一个的把节点加进去.那么这样一来看上去似乎就是一次操作O(nlogn),但是我们拥有数据结构的合并利器--启发式合并,那么我们就可以在均摊O(log2n)的时间内合并一颗树,这题就可以完美的AC啦! 什么,你问怎么维护重心?我们可以记录一个值sb表示子树的大小.怎么维护sb呢?我们可以采用打标记的方法,把新加入的节点到根的路径上的点的sb值都+1 对于维护答案,我们维护一个sm变量,来保存子树内所有节点到这个…
题目链接 BZOJ 洛谷 详见这. 求所有点到某个点距离和最短,即求树的重心.考虑如何动态维护. 两棵子树合并后的重心一定在两棵树的重心之间那条链上,所以在合并的时候用启发式合并,每合并一个点检查sz[]大的那棵子树的重心(记为root)最大子树的sz[]*2是否>n: 若>n,则向fa移动一次(先把合并点Splay到根).重心还一定是在sz[]大的那棵子树中,且移动次数不会超过sz[]小的子树的点数(所以总移动次数不会超过O(n)?). 复杂度 \(O(nlog^2n)\) 具体实现..想通…