合约数

 

借鉴了巨巨的代码,学会看数据量。

 题解:预处理得到每个Val的所有合约数,因为最大的Val才10000。然后在DFS的过程中,对每个节点u,先减去已经存在的u的合约数个数,当回溯到这个节点u的时候,加上u的合约数的个数(子树里面的合约数)。

 1 #pragma warning(disable:4996)
 2 #include<vector>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<iostream>
 6 #include<algorithm>
 7 #define ll long long 
 8 using namespace std;
 9 
10 const int maxn = 20005;
11 const int mod = 1000000007;
12 
13 vector<int> Tree[maxn], H[maxn];
14 
15 ll ans, F[maxn];
16 int n, p, kase, cnt[maxn], val[maxn];
17 bool prime[maxn], use[maxn];
18 
19 void Inite() {
20 
21     memset(prime, 0, sizeof(prime));
22     prime[0] = prime[1] = true;
23 
24     for (int i = 2; i <= 100; i++) if (!prime[i]) {
25         for (int j = i * i; j <= 10000; j += i) {
26             prime[j] = true;
27         }
28     }
29 
30     for (int i = 4; i <= 10000; i++) if (prime[i]) {
31         for (int j = 4; j <= i; j++) if (prime[j] && (i % j == 0)) {
32             H[i].push_back(j);
33         }
34     }
35 }
36 
37 void DFS(int u) {
38     for (int i = 0; i < H[val[u]].size(); i++) F[u] -= cnt[H[val[u]][i]];
39     cnt[val[u]]++;
40     for (int i = 0; i < Tree[u].size(); i++) {
41         int v = Tree[u][i];
42         if (!use[v]) {
43             use[v] = 1;
44             DFS(v);
45         }
46     }
47     for (int i = 0; i < H[val[u]].size(); i++) F[u] += cnt[H[val[u]][i]];
48     ans += 1LL * u * F[u];
49     ans %= mod;
50 }
51 
52 int main()
53 {
54     Inite();
55     scanf("%d", &kase);
56     while (kase--) {
57         scanf("%d%d", &n, &p);
58 
59         memset(F, 0, sizeof(F));
60         memset(cnt, 0, sizeof(cnt));
61         memset(use, 0, sizeof(use)); 
62 
63         use[p] = 1;
64         for (int i = 1; i <= n; i++) Tree[i].clear();
65 
66         for (int i = 2; i <= n; i++) {
67             int u, v;
68             scanf("%d%d", &u, &v);
69             Tree[u].push_back(v);
70             Tree[v].push_back(u);
71         }
72         for (int i = 1; i <= n; i++) {
73             scanf("%d", val + i);
74         }
75         
76         ans = 0;
77         DFS(p);
78         printf("%lld\n", ans);
79     }
80     return 0;
81 }

 

posted @ 2018-04-21 12:57  天之道,利而不害  阅读(308)  评论(0编辑  收藏  举报