小红的小红树(小红书24秋招后端开发)
题面
核心思想
首先我们任选一个节点为根节点
两数和为质数 只能染其中一个,那染父节点还是儿子节点呢?
我们自底向上的考虑,只需要贪心的只染儿子节点,因为儿子节点只有一个父节点,染了儿子节点也不会和其他节点产生冲突。
所以这样思考的话,我们同样自底向上的递归,只要相邻节点满足条件 则答案+1
质数的判断用的欧拉筛
代码
import java.util.*;
import java.util.function.Consumer;
public class Main {
static boolean[] isNotPrime; // true 表示为合数
static int[] value;
static List<Integer>[] next;
static int res;
public static void main(String[] args) {
final long MOD = (long) (1e9 + 7);
// 题目数据 a 最大为1e5 两数相加最大2e5 所以我们只需要筛出2e5之前的素数即可
final int MAXN = (int) (2e5 + 10);
// 欧拉筛
isNotPrime = new boolean[MAXN];
List<Integer> primes = new ArrayList<>();
for(int i = 2; i < MAXN; i++){
if(!isNotPrime[i])
primes.add(i);
for(int prime: primes){
if(i * prime >= MAXN)
break;
isNotPrime[i * prime] = true;
if(i % prime == 0)
break;
}
}
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
value = new int[n + 1];
next = new List[n + 1];
//保存节点值
for(int i = 1; i <= n; i++) {
value[i] = scanner.nextInt();
next[i] = new ArrayList<>();
}
//建树
for(int i = 1; i < n; i++) {
int x = scanner.nextInt();
int y = scanner.nextInt();
next[x].add(y);
next[y].add(x);
}
// 把1看作根节点
dfs(1, -1);
System.out.println(res);
}
private static void dfs(int cur, int pre){
for(int nxt: next[cur]){
if(nxt == pre) // pre为父节点 防止反走
continue;
dfs(nxt, cur);
int check = value[cur] + value[nxt];
//能染就染 反正染的是儿子节点 不关父节点的事
if(!isNotPrime[check]){
res++;
}
}
}
}
本文作者:Shie1d
本文链接:https://www.cnblogs.com/ganyq/p/18124015
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步