CF600E:Lomsat gelral(线段树合并)

本文介绍了一种使用线段树合并模板解决树结构中子树最多颜色编号和的问题。通过递归构建线段树,并利用Merge函数进行节点合并,最终实现对树中每个子树的颜色编号和的计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

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

Input

第一行一个$n$。第二行$n$个数字是$c[i]$。后面$n-1$行给出树边。

Output

一行答案。

Sample Input1

4
1 2 3 4
1 2
2 3
2 4

Sample Output1

10 9 3 4

Sample Input2

15
1 2 3 1 2 3 3 1 1 3 2 2 1 2 3
1 2
1 3
1 4
1 14
1 15
2 5
2 6
2 7
3 8
3 9
3 10
4 11
4 12
4 13

Sample Output2

6 5 4 3 2 3 3 1 1 3 2 2 1 2 3

Solution

线段树合并模板题,但我竟然读错题了QAQ……
情况特殊所以$Merge$的时候要加上$l$,$r$。
没啥好说的看代码就能懂……

Code

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #define N (100009)
 5 #define LL long long
 6 using namespace std;
 7 
 8 struct Sgt{int ls,rs,max; LL val;}Segt[N*50];
 9 struct Edge{int to,next;}edge[N<<1];
10 int n,x,u,v,sgt_num,c[N],Root[N];
11 int head[N],num_edge;
12 
13 void add(int u,int v)
14 {
15     edge[++num_edge].to=v;
16     edge[num_edge].next=head[u];
17     head[u]=num_edge;
18 }
19 
20 void Pushup(int now)
21 {
22     int ls=Segt[now].ls, rs=Segt[now].rs;
23     if (Segt[ls].max==Segt[rs].max)
24     {
25         Segt[now].max=Segt[ls].max;
26         Segt[now].val=Segt[ls].val+Segt[rs].val;
27     }
28     else if (Segt[ls].max>Segt[rs].max)
29     {
30         Segt[now].max=Segt[ls].max;
31         Segt[now].val=Segt[ls].val;
32     }
33     else
34     {
35         Segt[now].max=Segt[rs].max;
36         Segt[now].val=Segt[rs].val;
37     }
38 }
39 
40 void Update(int &now,int l,int r,int v)
41 {
42     if (!now) now=++sgt_num;
43     if (l==r)
44     {
45         Segt[now].max=1;
46         Segt[now].val=v;
47         return;
48     }
49     int mid=(l+r)>>1;
50     if (v<=mid) Update(Segt[now].ls,l,mid,v);
51     else Update(Segt[now].rs,mid+1,r,v);
52     Pushup(now);
53 }
54 
55 int Merge(int x,int y,int l,int r)
56 {
57     if (!x || !y) {return x|y;}
58     int tmp=++sgt_num;
59     if (l==r)
60     {
61         Segt[tmp].max=Segt[x].max+Segt[y].max;
62         Segt[tmp].val=l; return tmp;
63     }
64     int mid=(l+r)>>1;
65     Segt[tmp].ls=Merge(Segt[x].ls,Segt[y].ls,l,mid);
66     Segt[tmp].rs=Merge(Segt[x].rs,Segt[y].rs,mid+1,r);
67     Pushup(tmp); return tmp;
68 }
69 
70 void DFS(int x,int fa)
71 {
72     for (int i=head[x]; i; i=edge[i].next)
73         if (edge[i].to!=fa)
74         {
75             DFS(edge[i].to,x);
76             Root[x]=Merge(Root[x],Root[edge[i].to],1,n);
77         }
78 }
79 
80 int main()
81 {
82     scanf("%d",&n);
83     for (int i=1; i<=n; ++i)
84     {
85         scanf("%d",&c[i]);
86         Update(Root[i],1,n,c[i]);
87     }
88     for (int i=1; i<=n-1; ++i)
89     {
90         scanf("%d%d",&u,&v);
91         add(u,v); add(v,u);
92     }
93     DFS(1,0);
94     for (int i=1; i<=n; ++i)
95         printf("%lld ",Segt[Root[i]].val);
96 }

转载于:https://www.cnblogs.com/refun/p/10057599.html

资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建与发布是提升开发效率和项目质量的关键环节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建与发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排与可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称和描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本和预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建和发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了四个阶段:Checkout、Build、Push package和Deploy/Rollback。每个阶段都可以根据实际需求进行配置和调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率和项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试和部署,从而提高项目的整体质量和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值