热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

牛客xb赛48F孤独的树树形dp处理森林筛法

题目传送门题解思路因为N最大就是1e5,所以对与每个权值他最多只能有6个不同的质因子。我们每次只能去除一个质因子,所以,如果要去除这个

题目

在这里插入图片描述
传送门


题解思路

因为N最大就是1e5,所以对与每个权值他最多只能有6个不同的质因子。
我们每次只能去除一个质因子,所以,如果要去除这个点的这种质因子就多次去除这个即可。

我们从最大的质因子不断往小删。这样就能O1获取我们此时到底要删谁。

有相同质因子的点可以构成森林(多个连通块),我们对每个连通块,每次都处理掉一种质因子,这样就能保证复杂度在Nlog(N)。

对于每个连通块处理同种质因子有树形dp来计算最小的次数,最后再累加。

dp[i][0] 表示以i为根节点的子树,根节点不进行删除操作使得满足题目条件的最小次数。

dp[i][1]就表示进行操作的最小次数。

最后在根节点取min即可。


AC代码

#include
//#include
//priority_queue
#define PII pair<int,int>
#define ll long longusing namespace std;const int INF &#61; 0x3f3f3f3f;
const int N &#61; 200100;
int a[N] ;
vector <int> head[N] ;
set <int> vis[N] ;
int f[N][3] ;
int np[N] ;
int mnp[N] ;
void si()
{for (int i &#61; 2 ; i <&#61; 1e5 &#43; 5 ; i&#43;&#43; ){if (!np[i]){for (int j &#61; i ; j <&#61; 1e5 &#43; 5 ; j &#43;&#61; i ){np[j] &#61; 1 ; mnp[j] &#61; i ; }}}
}
void dfs(int x , int p )
{vis[x].insert(p) ; int cnt &#61; 0 ; while ( a[x] % p &#61;&#61; 0 )a[x]/&#61;p,cnt&#43;&#43;;int sum1 &#61; 0 ,sum0 &#61; 0 ; for (int i &#61; 0 ; i < head[x].size() ; i&#43;&#43; ){int sk &#61; head[x][i] ;if ( !vis[sk].count(p) && a[sk] % p &#61;&#61; 0 ){dfs(sk,p) ; sum0 &#43;&#61; min(f[sk][0],f[sk][1]) ; sum1 &#43;&#61; f[sk][1] ; }}f[x][0] &#61; sum1 ; f[x][1] &#61; sum0 &#43; cnt ;
}
void solve()
{si();int n ;cin >> n ; for (int i &#61; 1 ; i <&#61; n ; i&#43;&#43; )cin >> a[i] ; for (int i &#61; 1 ; i < n ; i&#43;&#43; ){int t1 , t2 ;cin >> t1 >> t2 ; head[t1].push_back(t2) ; head[t2].push_back(t1) ; }int ans &#61; 0 ; for (int i &#61; 1 ; i <&#61; n ; i&#43;&#43; ){while ( a[i] !&#61; 1 ){int p &#61; mnp[a[i]] ; if (!vis[i].count(p)){dfs(i,p) ; ans &#43;&#61; min(f[i][1],f[i][0]) ; }}}cout << ans << "\n";
}
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);solve() ;return 0 ;
}

推荐阅读
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • 本文探讨了如何在模运算下高效计算组合数C(n, m),并详细介绍了乘法逆元的应用。通过扩展欧几里得算法求解乘法逆元,从而实现除法取余的计算。 ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • 本题探讨了一种字符串变换方法,旨在判断两个给定的字符串是否可以通过特定的字母替换和位置交换操作相互转换。核心在于找到这些变换中的不变量,从而确定转换的可能性。 ... [详细]
  • 题目描述:给定n个半开区间[a, b),要求使用两个互不重叠的记录器,求最多可以记录多少个区间。解决方案采用贪心算法,通过排序和遍历实现最优解。 ... [详细]
  • C++: 实现基于类的四面体体积计算
    本文介绍如何使用C++编程语言,通过定义类和方法来计算由四个三维坐标点构成的四面体体积。文中详细解释了四面体体积的数学公式,并提供了两种不同的实现方式。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本文探讨了 C++ 中普通数组和标准库类型 vector 的初始化方法。普通数组具有固定长度,而 vector 是一种可扩展的容器,允许动态调整大小。文章详细介绍了不同初始化方式及其应用场景,并提供了代码示例以加深理解。 ... [详细]
  • 本文详细探讨了VxWorks操作系统中双向链表和环形缓冲区的实现原理及使用方法,通过具体示例代码加深理解。 ... [详细]
  • 本文详细探讨了KMP算法中next数组的构建及其应用,重点分析了未改良和改良后的next数组在字符串匹配中的作用。通过具体实例和代码实现,帮助读者更好地理解KMP算法的核心原理。 ... [详细]
  • 本文详细介绍了如何构建一个高效的UI管理系统,集中处理UI页面的打开、关闭、层级管理和页面跳转等问题。通过UIManager统一管理外部切换逻辑,实现功能逻辑分散化和代码复用,支持多人协作开发。 ... [详细]
  • 本文探讨了 Objective-C 中的一些重要语法特性,包括 goto 语句、块(block)的使用、访问修饰符以及属性管理等。通过实例代码和详细解释,帮助开发者更好地理解和应用这些特性。 ... [详细]
  • 本文详细介绍了 Apache Jena 库中的 Txn.executeWrite 方法,通过多个实际代码示例展示了其在不同场景下的应用,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 本文介绍了如何通过 Maven 依赖引入 SQLiteJDBC 和 HikariCP 包,从而在 Java 应用中高效地连接和操作 SQLite 数据库。文章提供了详细的代码示例,并解释了每个步骤的实现细节。 ... [详细]
  • 本实验主要探讨了二叉排序树(BST)的基本操作,包括创建、查找和删除节点。通过具体实例和代码实现,详细介绍了如何使用递归和非递归方法进行关键字查找,并展示了删除特定节点后的树结构变化。 ... [详细]
author-avatar
夜夜0603
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有