codeforces600E. Lomsat gelral(dsu on tree)】的更多相关文章

dsu on tree先分轻重儿子先处理轻边,再处理重儿子再加上轻儿子的答案 #include<iostream> #include<cstdio> #include<queue> #include<algorithm> #include<cmath> #include<ctime> #include<set> #include<map> #include<stack> #include<cs…
[题目]E. Lomsat gelral [题意]给定n个点的树,1为根,每个点有一种颜色ci,一种颜色占领一棵子树当且仅当子树内没有颜色的出现次数超过它,求n个答案——每棵子树的占领颜色的编号和Σci(一棵子树可能有多种占领颜色).1<=n,ci<=10^5. [算法]dsu on tree [题解]入门题,讲一下dsu on tree算法. 一.dsu on tree的适用范围:①子树询问,②支持数组上的快速信息加,③不带修.(注意不需要支持信息删除,只需要能清空信息) 如果写暴力的时候,…
题目链接 dsu on tree详见这. \(Description\) 给定一棵树.求以每个点为根的子树中,出现次数最多的颜色的和. \(Solution\) dsu on tree模板题. 用\(sum[i]\)表示出现次数为\(i\)的颜色的和,\(cnt[i]\)表示出现次数为\(i\)的颜色有多少个(其实用个\(Max\)表示当前最多的次数,和每种颜色出现次数\(tm[i]\)就好了),然后..就这样了.. 可以用DFS序代替DFS减少一些常数. 再写一遍dsu on tree大体过程…
题目链接:http://codeforces.com/problemset/problem/600/E n个点的有根树,以1为根,每个点有一种颜色.我们称一种颜色占领了一个子树当且仅当没有其他颜色在这个子树中出现得比它多.求占领每个子树的所有颜色之和. 我们都知道可以$BST$启发式合并从而完美${O(nlogn^{2})}$,这太丑陋了. 那么$Dsu~~on~~tree$是在干啥呢? 找出树中每一个节点的重儿子,统计答案的时候优先进入每一个点的所有轻儿子,之后再进入重儿子,目的是保留重儿子所…
题意 题目链接 给出一个树,求出每个节点的子树中出现次数最多的颜色的编号和 Sol dsu on tree的裸题. 一会儿好好总结总结qwq #include<bits/stdc++.h> #define LL long long using namespace std; ; inline int read() { , f = ; ; c = getchar();} + c - ', c = getchar(); return x * f; } int N, col[MAXN], son[MA…
解题思路 \(dsu\) \(on\) \(tree\)的模板题.暴力而优雅的算法,轻儿子的信息暴力清空,重儿子的信息保留,时间复杂度\(O(nlogn)\) 代码 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<set> using namespace std; const int…
[Codeforces600E] Lomsat gelral(树上启发式合并) 题面 给出一棵N个点的树,求其所有子树内出现次数最多的颜色编号和.如果多种颜色出现次数相同,那么编号都要算进答案 N≤100000 分析 树上启发式合并,用map记录颜色出现次数,合并的时候更新最多的出现次数和编号和. 注意合并时的下标问题.当我们merge(x,y)的时候,由于是启发式合并,s[x]可能会并到s[y]去,如果我们直接查询s[x],就查不到真正的答案.所以要再建立一个数组id[x],记录x的map合并…
第一次AC这道题,是三年前的一个下午,也许晚上也说不定.当时使用的\(DSU\) \(on\) \(tree\)算法,如今已经淡忘,再学习新的算法过程中,却与旧物重逢.生活中充满不可知会的相遇,即使重逢时多是物是人非.我又想起十六岁时在上海那个船上的夜晚,两岸的霓虹在无边黑暗中照亮了她的脸庞,绿衣在少年的眼瞳里凝滞了时间,那真是个美丽的夜晚,即使看不见星月.前天她给我说说点了个赞,我都高兴了好久,真是卑微呵.那么人世中所有明知卑微却不求告解的人,就是可悲吗?大抵是有更深沉的缘由的,比如最初的悸动…
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/转载请注明出处,侵权必究,保留最终解释权! 题目链接:codeforces600E 解法一:$O(nlog^2n)$ 正解:启发式合并 解题报告: 这道题求的是每个点的子树内的出现次数最大的数字的和. 考虑启发式合并,我用$col[x]$的$map$表示$x$的子树内的每种权值的出现次数,$sum[…
题目链接 题意:给你一棵以1为根n个点的树,问你以i为根的子树的众数和是多少 思路:dsu是一种优化暴力的手段 首先进行轻重链剖分 然后只记录重链的信息 轻链的信息就直接暴力查找 经过证明这样复杂度可以是nlogn. #include<bits/stdc++.h> #define ll long long int using namespace std; inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;} inline ll lcm(ll a,ll…
从树上启发式合并搜出来的题 然而看着好像线段树合并就能解决??? 那么就用线段树合并解决吧 维护\(max, sum\)表示值域区间中的一个数出现次数的最大值以及所有众数的和即可 复杂度\(O(n \log n)\) #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define ll long long #d…
先瞎扯几句 说起来我跟这个算法好像还有很深的渊源呢qwq.当时在学业水平考试的考场上,题目都做完了不会做,于是开始xjb出题.突然我想到这么一个题 看起来好像很可做的样子,然而直到考试完我都只想出来一个莫队的暴力.当时我想知道有没有比莫队更优的做法,和zbq讨论了半天也只能搞出一个$O(nlog^2n)$的平衡树启发式合并 然后!!我就把这题出给校内互测了!!没错,当时是用莫队当的标算! 结果!mjt用一个假的$O(n)$算法艹过去了因为数据特别水 后来我打算把这题出给另一场比赛,结果到了前一天…
题面:codeforces600E 学习一下$dsu \ on \ tree$.. 这个东西可以处理很多无修改子树问题,复杂度通常为$O(nlogn)$. 主要操作是:我们先把整棵树链剖一下,然后每次先递归轻儿子,再递归重儿子. 对于每棵子树,我们暴力加入整棵子树的贡献.如果是重儿子的子树则另外处理:加入贡献时不考虑加重儿子所在的子树,而在消除贡献时也不消除重儿子的子树,直到它成为某个点的轻儿子的子树的一部分时再消除贡献. 复杂度:因为每个轻儿子最多被加入$O(logn)$次(递归轻儿子时$si…
[CF600E]Lomsat gelral(dsu on tree) 题面 洛谷 CF题面自己去找找吧. 题解 \(dsu\ on\ tree\)板子题 其实就是做子树询问的一个较快的方法. 对于子树的询问,我们不难想到子树就是\(dfs\)序上的连续一段, 可以把树转化成序列再用莫队来解. 其实可以对树进行树链剖分,然后暴力+优化来解 具体的做法就是: 递归处理轻儿子,计算轻儿子答案, 然后消去轻儿子对于答案的影响. 然后递归处理重儿子,不消去影响,最后加入所有轻儿子贡献,计算答案. 复杂度?…
有这么一类问题,要求统计一棵树上与子树相关的某些信息,比如:在一棵所有节点被染色的树上,统计每棵子树上出现次数最多的颜色编号之和. 很自然的可以想到用DFS序+主席树去求解,但是编码复杂度很高: 然后我们可以想到DFS序+莫队解决,然而$O(n\sqrt{n})$的时间复杂度在数据较大的时候容易TLE: 有没有更优美一点的解法呢?DSU On Tree(据说叫树上启发式合并)可以以较小的编码复杂度在$O(n\log n)$的时间复杂度完成对于所有子树信息的统计. 先上模板 void dsu(LL…
dsu on tree跟冰茶祭有什么关系啊喂 dsu on tree的模板题 思想与解题过程 类似树链剖分的思路 先统计轻儿子的贡献,再统计重儿子的贡献,得出当前节点的答案后再减去轻儿子对答案的贡献 似乎很蠢 但是复杂度是\(O(nlogn)\)的,在没有修改的情况下,可以把树上莫队吊起来打 没了 代码实现 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int…
dsu on tree板子题.这个trick保证均摊O(nlogn)的复杂度,要求资瓷O(1)将一个元素插入集合,清空集合时每个元素O(1)删除.(当然log的话就变成log^2了) 具体的,每次先遍历轻儿子的子树,暴力求得所需信息,每遍历完一棵轻子树都将其信息清空.然后遍历重子树,暴力求得所需信息,保留信息,再重新遍历轻子树将信息合并,最后加上根本身得到原子树的信息. 复杂度证明考虑每个点的信息被统计的次数,显然这只与其到根的路径上轻边条数有关,于是复杂度O(nlogn). #include<…
With $Dsu \ on \ tree$ we can answer queries of this type: How many vertices in the subtree of vertex $v$ has some property in $O (n \log n)$ time (for all of the queries)? 这题写的是轻重儿子(重链剖分)版本的 $Dsu \ on \ tree$ 具体流程如下: 每次先递归计算轻儿子,再单独递归重儿子,计算完后轻儿子的一些信息…
题意 一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. dsu on tree 用来解决子树问题 好像不能带修改?? 暴力做这个题,就是每次扫一遍子树统计答案 时间\(O(n^2)\) 或者会高级的数据结构解决 空间,编程难度是个挑战 然而\(dsu \ on \ tree\)树上启发式合并则是一个好方法 它通过增加对重儿子子树信息的利用来提高效率 流程: 递归轻儿子 递归重儿子 统计答案 如果该点为它父亲的重儿子,保存信息 否则删除信息 复杂度分…
题目描述 一棵树有$n$个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. 这个题意是真的窒息...具体意思是说,每个节点有一个颜色,你要找的是每个子树中颜色的众数(可能有多个),比如子树中有$3个2,3个1,3个5,那么2,1,5都是众数,答案为2+1+5=8$. 思路 做法一: 线段树合并.权值线段树覆盖颜色$1->100000,用sum$表示颜色最多出现的次数,$ans$表示答案.分$3种情况pushup$即可. 左右子树$sum$相等 左边$>$右边…
传送门 题意: 求子树众数. 思路: \(dsu\ on\ tree\)模板题,用一个桶记录即可. 感觉\(dsu\ on\ tree\)这个算法的涉及真是巧妙呀,保留重链的信息,不断暴力轻边,并且不断在子树内递归下去.又由于轻边数量不会超过\(O(logn)\),所以总的时间复杂度控制在\(O(nlogn)\). /* * Author: heyuhhh * Created Time: 2019/11/13 15:09:25 */ #include <bits/stdc++.h> #defi…
传送门 一道烂大街的dsu on tree板题. 感觉挺有趣的^_^ 代码真心简单啊! 就是先处理轻儿子,然后处理重儿子,其中处理轻儿子后需要手动消除影响. 代码: #include<bits/stdc++.h> #define N 100005 #define ll long long using namespace std; inline int read(){ int ans=0; char ch=getchar(); while(!isdigit(ch))ch=getchar(); w…
十几天前看到zyf2000发过关于这个的题目的Blog, 今天终于去学习了一下 Codeforces原文链接 dsu on tree 简介 我也不清楚dsu是什么的英文缩写... 就像是树上的启发式合并 用到了\(heavy-light\ decomposition\)树链剖分 把轻边子树的信息合并到重链上的点里 因为每次都是先dfs轻儿子再dfs重儿子,只有重儿子子树的贡献保留,所以可以保证dfs到每颗子树时当前全局维护的信息不会有别的子树里的,和莫队很像 算法过程 find the BigC…
近几天跟着dreagonm大佬学习了\(dsu\ on\ tree\),来总结一下: \(dsu\ on\ tree\),也就是树上启发式合并,是用来处理一类离线的树上询问问题(比如子树内的颜色种数)的不二法宝.它不仅好想好写,还有着\(O(nlogn)\)的优秀时间复杂度(划重点). 结合一道例题来讲吧: CF600E Lomsat gelral 题目大意: 一棵树有\(n(n\leqslant 10^5)\)个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和…
CF600E Lomsat gelral Solution 考虑一下子树的问题,我们可以把一棵树的dfn序搞出来,那么子树就是序列上的一段连续的区间. 然后就可以莫队飞速求解了. 但是这题还有\(\Theta(nlog_n)\)的做法.能有\(\Theta(n\sqrt{n})\)的做法要什么\(logn\)的 考虑\(dsu\ on\ tree\),与莫队没有任何区别. 如果不会的话,请自行跳转小Z的袜子并且切掉. 代码实现 #include<stdio.h> #include<std…
这个属于一种技巧,可以解决类似于子树询问无修改可离线的问题,一些点分治的问题也可以用Dsu on Tree解决,并且常数较小,代码复杂度低,很具有可写性. 整体上的意思就是继承重儿子的信息,暴力修改轻儿子的信息,时间复杂度的证明类似并查集的启发式合并(本质上这个就是启发式合并). 通常情况下,题目长成询问某种东西的数量,或者某种点对的数量. 例题时间 Educational Codeforces Round 2 E Lomsat gelral $n$个点的有根树,以$1$为根,每个点有一种颜色.…
我也不知道为啥这要起这名,完完全全没看到并查集的影子啊…… 实际上原理就是一个树上的启发式合并. 特点是可以在$O(nlogn)$的时间复杂度内完成对无修改的子树的统计,复杂度优于莫队算法. 局限性也很明显:1.不能支持修改  2.只能支持子树统计,不能链上统计.(链上统计你不能直接树剖吗?) 那么它是怎么实现的呢?首先有一个例子:树上每个节点都有一个颜色(那么一定是蓝色), 求每个节点的子树上有多少颜色为k的节点.(每个节点的k不一定相同) $O(n^2)$的算法非常好想,以每个点为起点dfs…
DSU on tree 在之前的一次比赛中,学长向我们讲了了这样一个神奇的思想:DSU on tree(树上启发式合并),看上去就非常厉害--但实际上是非常暴力的一种做法;不过暴力只是看上去暴力,它在处理不带修改的子树统计问题时有着优秀的时间复杂度\(O(Nlog N)\),显然在处理这一类问题上,它是优于我们常用的\(dfs\)序后莫队,更关键是它十分好写. 算法实现: 首先对所有轻儿子的子树信息进行统计,然后暴力擦除所有轻儿子的影响.再统计重儿子为根的子树信息,并将轻儿子的信息合并起来,加上…
有丶难,学到自闭 参考的文章: zcysky:[学习笔记]dsu on tree Arpa:[Tutorial] Sack (dsu on tree) 先康一康模板题吧:CF 600E($Lomsat$ $gelral$) 虽然已经用莫队搞过一遍了(可以参考之前写的博客~),但这个还是差距挺大 我们如果对于每个节点暴力统计答案,是$O(N^2)$的复杂度:最坏情况下整棵树是一条链,对于每个节点的统计平均下来是$O(N)$的 具体是怎么做的呢? 对于以当前节点$x$为根的子树,我们建立$cnt$和…
dsu on tree 树上启发式合并.我并不知道为什么要叫做这个名字... 干什么的 可以在\(O(n\log n)\)的时间内完成对子树信息的询问,可横向对比把树按\(dfs\)序转成序列问题的\(O(n\sqrt n)\)莫队算法. 怎么实现 当\(dfs\)到一个点\(u\),执行以下操作: 1.递归处理所有轻儿子; 2.递归处理重儿子; 3.计算整棵子树的贡献(在第2步中重儿子的贡献得以保留,所以不需要重复计算); 4.若点\(u\)不是其父亲的重儿子,删除整棵子树的贡献. 看上去像是…