• B 合约数


    链接:https://www.nowcoder.com/acm/contest/91/B
    来源:牛客网

    题目描述

    在埃森哲,员工培训是最看重的内容,最近一年,我们投入了 9.41 亿美元用于员工培训和职业发展。截至 2018 财年末,我们会在全球范围内设立 100 所互联课堂,将互动科技与创新内容有机结合起来。按岗培训,按需定制,随时随地,本土化,区域化,虚拟化的培训会让你快速取得成长。小埃希望能通过培训学习更多ACM 相关的知识,他在培训中碰到了这样一个问题,

    给定一棵n个节点的树,并且根节点的编号为p,第i个节点有属性值vali, 定义F(i): 在以i为根的子树中,属性值是vali的合约数的节点个数。y 是 x 的合约数是指 y 是合数且 y 是 x 的约数。小埃想知道对1000000007取模后的结果.

    输入描述:

    输入测试组数T,每组数据,输入n+1行整数,第一行为n和p,1<=n<=20000, 1<=p<=n, 接下来n-1行,每行两个整数u和v,表示u和v之间有一条边。第n+1行输入n个整数val1, val2,…, valn,其中1<=vali<=10000,1<=i<=n.

    输出描述:

    对于每组数据,输出一行,包含1个整数, 表示对1000000007取模后的结果

    示例1

    输入

    2
    5 4
    5 3
    2 5
    4 2
    1 3
    10 4 3 10 5
    3 3
    1 3
    2 1
    1 10 1

    输出

    11
    2

    备注:

    n>=10000的有20组测试数据

    dfs问题,先预处理下10000之内的每个合约数,然后从根节点p开始遍历,每次删除前面出现的合约数,等回溯后就加上当前的合约数,这样就可以得到当前的合约数了。

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <cstring>
     4 #include <vector>
     5 using namespace std;
     6 const int mod = 1000000007;
     7 const int M = 20010;
     8 vector<int> vs[M], H[M];
     9 bool vis[M];
    10 int val[M], F[M], ans, cnt[M];
    11 void init() {
    12     vis[0] = vis[1] = true;
    13     for(int i = 2; i <= 100; i ++) {
    14         if(!vis[i]) {
    15             for(int j = i*i; j <= 10000; j += i) vis[j] = true;
    16         }
    17     }
    18     for(int i = 4; i <= 10000; ++ i) {
    19         if(vis[i]) {
    20             for(int j = 4; j <= i; ++ j) {
    21                 if(vis[j] && i%j == 0) H[i].push_back(j);
    22             }
    23         }
    24     }
    25 }
    26 void dfs(int u) {
    27     for(int i = 0; i < H[val[u]].size(); i ++) {
    28         F[u] -= cnt[H[val[u]][i]];
    29     }
    30     cnt[val[u]]++;
    31     for(int i = 0; i < vs[u].size(); i ++) {
    32         if(!vis[vs[u][i]]) {
    33             vis[vs[u][i]] = 1;
    34             dfs(vs[u][i]);
    35         }
    36     }
    37     for(int i = 0; i < H[val[u]].size(); i ++) {
    38         F[u] += cnt[H[val[u]][i]];
    39     }
    40     ans += 1LL*F[u]*u;
    41     ans %= mod;
    42 }
    43 int main() {
    44     init();
    45     //printf("%d
    ",H[10].size());
    46     int t, n, p;
    47     cin >> t;
    48     while(t--) {
    49         memset(vis,0,sizeof(vis));
    50         memset(F,0,sizeof(F));
    51         memset(cnt,0,sizeof(cnt));
    52         for(int i = 0; i <= M; i ++) vs[i].clear();
    53         ans = 0;
    54         cin >> n >> p;
    55         for(int i = 0; i < n-1; i ++) {
    56             int u, v;
    57             cin >> u >> v;
    58             vs[u].push_back(v);
    59             vs[v].push_back(u);
    60         }
    61         for(int i = 1; i <= n; i ++) cin >> val[i];
    62         vis[p] = 1;
    63         dfs(p);
    64         cout << ans << endl;
    65     }
    66     return 0;
    67 }
  • 相关阅读:
    PowerShell入门(十二):编写PowerShell管理单元和二进制模块
    WMI入门(二):如何使用WMI
    (算法)从10000个数中找出最大的10个
    WMI入门(三):我需要的类在哪里?
    WMI入门(一):什么是WMI
    C#高级编程:(一)Enterprise Services中遇到的问题
    PowerShell入门(九):访问.Net程序集、COM和WMI
    PowerShell入门(十一):编写脚本模块
    PowerShell入门(十):使用配置文件
    eclipse中的汉字极小的解决方案
  • 原文地址:https://www.cnblogs.com/xingkongyihao/p/8870132.html
Copyright © 2020-2023  润新知