[CF600E]Lomsat gelral

题意翻译

一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和。

线段树合并板子题,没啥难度,注意开long long

不过这题$dsu$ $on$ $tree$确实更快

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #define ls ch[node][0]
 4 #define rs ch[node][1]
 5 #define M 100010
 6 using namespace std;
 7 int n,m,num,cnt;
 8 int head[M],rt[M],co[M];
 9 int ch[M<<7][2],v1[M<<7];
10 long long v2[M<<7],ans[M];
11 struct point{int to,next;}e[M<<1];
12 void add(int from,int to) {
13     e[++num].next=head[from];
14     e[num].to=to;
15     head[from]=num;
16 }
17 void update(int node) {
18     if(v1[ls]==v1[rs]) {
19         v1[node]=v1[ls];v2[node]=v2[ls]+v2[rs];
20     }
21     else{
22         if(v1[ls]>v1[rs]) v1[node]=v1[ls],v2[node]=v2[ls];
23         else v1[node]=v1[rs],v2[node]=v2[rs];
24     }
25 }
26 void insert(int &node,int l,int r,int x) {
27     if(!node) node=++cnt;
28     if(l==r) {
29         v1[node]=1,v2[node]=x;return;
30     }int mid=(l+r)/2;
31     if(x<=mid) insert(ls,l,mid,x);
32     else insert(rs,mid+1,r,x);
33     update(node);
34 }
35 int merge(int x,int y,int l,int r) {
36     if(!x||!y) return x+y;
37     int node=++cnt;
38     if(l==r) {
39         v1[node]=v1[x]+v1[y];v2[node]=l;return node;
40     }
41     int mid=(l+r)/2;
42     ch[node][0]=merge(ch[x][0],ch[y][0],l,mid);
43     ch[node][1]=merge(ch[x][1],ch[y][1],mid+1,r);
44     update(node);return node;
45 }
46 void dfs(int x,int fa) {
47     insert(rt[x],1,n,co[x]);
48     for(int i=head[x];i;i=e[i].next) {
49         int to=e[i].to;
50         if(to==fa) continue;
51         dfs(to,x);
52         rt[x]=merge(rt[x],rt[to],1,n);
53     }
54     ans[x]=v2[rt[x]];
55 }
56 int main() {
57     scanf("%d",&n);
58     for(int i=1;i<=n;i++) scanf("%d",&co[i]);
59     for(int i=1;i<n;i++) {
60         int x,y;scanf("%d%d",&x,&y);
61         add(x,y),add(y,x);
62     }
63     dfs(1,0);
64     for(int i=1;i<=n;i++) printf("%lld ",ans[i]);
65     return 0;
66 }

原文地址:https://www.cnblogs.com/Slrslr/p/10043248.html

时间: 2024-10-05 04:03:25

[CF600E]Lomsat gelral的相关文章

CF600E Lomsat gelral 【线段树合并】

题目链接 CF600E 题解 容易想到就是线段树合并,维护每个权值区间出现的最大值以及最大值位置之和即可 对于每个节点合并一下两个子节点的信息 要注意叶子节点信息的合并和非叶节点信息的合并是不一样的 由于合并不比逐个插入复杂度高,所以应是\(O(nlogn)\)的 #include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #i

CF600E Lomsat gelral(线段树合并)

link 题目大意:给以1为根的一棵树,求树上每个点子树中出现次数最多的权值(如果有多个就求他们的和) 对每个点开一个线段树维护子树内权值的桶,dfs时候线段树合并就行了. 因为最后线段树一共插入最多 \(O(n\log n)\) 个节点,每个节点最多会被合并一次,所以复杂度是 \(O(n\log n)\) 的. #include <cstdio> #include <vector> using namespace std; struct fuck { int maxval; lo

【CF600E】 Lomsat gelral

CF600E Lomsat gelral Solution 考虑一下子树的问题,我们可以把一棵树的dfn序搞出来,那么子树就是序列上的一段连续的区间. 然后就可以莫队飞速求解了. 但是这题还有\(\Theta(nlog_n)\)的做法.能有\(\Theta(n\sqrt{n})\)的做法要什么\(logn\)的 考虑\(dsu\ on\ tree\),与莫队没有任何区别. 如果不会的话,请自行跳转小Z的袜子并且切掉. 代码实现 #include<stdio.h> #include<std

【题解】Lomsat gelral [CF600E]

[题解]Lomsat gelral [CF600E] [前言] 写完 \(\text{Dsu on tree}\) 后大致浏览了网上的题解,常见做法有以下几种: \(\text{Dsu on tree}\)(占大多数,毕竟是板子) 线段树合并(空间巨大) \(O(n\sqrt{n}logn)\) 的 \(\text{DFS}\) 序 \(+\) \(sb\) 暴力莫队(时间巨大) \(O(n\sqrt{n})\) 的 \(\text{DFS}\) 序 \(+\) 回滚莫队(效率一般) 但就是没找

Codeforces 600E Lomsat gelral (Dsu On the Tree)

题目链接 Lomsat gelral 占坑--等深入理解了再来补题解-- 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define rep(i, a, b) for (int i(a); i <= (b); ++i) 6 7 typedef long long LL; 8 9 const int N = 600010; 10 11 int n; 12 int cc[N], col[N], sz[N], son[N];

CF 600 E. Lomsat gelral

E. Lomsat gelral http://codeforces.com/contest/600/problem/E 题意: 求每个子树内出现次数最多的颜色(如果最多的颜色出现次数相同,将颜色编号求和). 分析: dsu on tree. 这个可以解决一系列不带修改的子树查询问题. 考虑暴力的思路:就是枚举每个子树,计算每个颜色出现的个数.统计答案. dsu on tree:最后一个子树枚举计算完了,它的贡献可以保留,然后用其它的子树去合并.(最后一棵子树是最大的).现在的复杂度就是nlog

【CF600E】Lomsat gelral——树上启发式合并

(题面来自luogu) 题意翻译 一棵树有n个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. ci <= n <= 1e5 树上启发式合并裸题.统计时先扫一遍得到出现次数最大值,然后再扫一遍看哪个颜色的出现次数与mxCnt相等.注意用一个bool数组判重,清空轻儿子贡献时要顺手把bool数组也打成false. 代码: #include <iostream> #include <cstdio> #include <cctype&

Codeforces 600E. Lomsat gelral(Dsu on tree学习)

题目链接:http://codeforces.com/problemset/problem/600/E n个点的有根树,以1为根,每个点有一种颜色.我们称一种颜色占领了一个子树当且仅当没有其他颜色在这个子树中出现得比它多.求占领每个子树的所有颜色之和. 我们都知道可以$BST$启发式合并从而完美${O(nlogn^{2})}$,这太丑陋了. 那么$Dsu~~on~~tree$是在干啥呢? 找出树中每一个节点的重儿子,统计答案的时候优先进入每一个点的所有轻儿子,之后再进入重儿子,目的是保留重儿子所

codeforces600E Lomsat gelral

本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/转载请注明出处,侵权必究,保留最终解释权! 题目链接:codeforces600E 正解:启发式合并 解题报告: 这道题求的是每个点的子树内的出现次数最大的数字的和. 考虑启发式合并,我用$col[x]$的$map$表示$x$的子树内的每种权值的出现次数,$sum[x]$的$map$表示$x$的子树