码迷,mamicode.com
首页 > 其他好文 > 详细

埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 B合约数

时间:2018-05-15 00:32:40      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:ack   esc   ext   ons   amp   memset   bubuko   题目   lin   

链接:https://www.nowcoder.com/acm/contest/91/B
来源:牛客网
牛客网没有账号的同学,请用这个注册,支持楼主,谢谢。

技术分享图片

题目描述

给定一棵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组测试数据



大意见题面
题解:
首先筛素数,然后把每个合数的约数预处理出来,放在vector里面。
然后从根开始dfs,统计子树中每个val的出现次数,统计进入子树前和从子树回来时增加的出现次数即为F函数的值。
累加答案。
技术分享图片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<ctime>
 5 #include<cstdlib>
 6 #include<algorithm>
 7 #include<cmath>
 8 #include<string>
 9 #include<vector>
10 #include<map>
11 #include<set>
12 using namespace std;
13 int read(){
14     int xx=0,ff=1;char ch=getchar();
15     while(ch>9||ch<0){if(ch==-)ff=-1;ch=getchar();}
16     while(ch>=0&&ch<=9){xx=xx*10+ch-0;ch=getchar();}
17     return xx*ff;
18 }
19 const int MOD=1000000007;
20 const int maxn=20010;
21 int N,rt,val[maxn];
22 int lin[maxn],len;
23 struct edge{
24     int y,next;
25 }e[maxn<<1];
26 inline void insert(int xx,int yy){
27     e[++len].next=lin[xx];
28     lin[xx]=len;
29     e[len].y=yy;
30 }
31 inline void ins(int xx,int yy)
32 {insert(yy,xx),insert(xx,yy);}
33 bool vis[maxn];
34 int prime[maxn],cnt=0;
35 vector<int>v[maxn];
36 void pre_prime(){
37     for(int i=2;i<=10000;i++)
38         if(!vis[i]){
39             prime[++cnt]=i;
40             for(int j=i*i;j<=10000;j+=i)
41                 vis[j]=1;
42         }
43     for(int i=2;i<=10000;i++)
44         if(vis[i])
45             for(int j=i;j<=10000;j+=i)
46                 v[j].push_back(i);
47 }
48 int ans,p[maxn];
49 void dfs(int x,int fa){
50     int sum=0;
51     for(int i=0;i<v[val[x]].size();i++)
52         sum-=p[v[val[x]][i]];
53     for(int i=lin[x];i;i=e[i].next)
54         if(e[i].y!=fa)
55             dfs(e[i].y,x);
56     p[val[x]]++;
57     for(int i=0;i<v[val[x]].size();i++)
58         sum+=p[v[val[x]][i]];
59     (ans+=x*sum)%=MOD;
60 }
61 int main(){
62     //freopen("in.txt","r",stdin);
63     pre_prime();
64     for(int T=read();T;T--){
65         memset(lin,0,sizeof(lin));len=0;
66         N=read(),rt=read();
67         for(int i=1;i<N;i++)
68             ins(read(),read());
69         for(int i=1;i<=N;i++)
70             val[i]=read();
71         ans=0;
72         memset(p,0,sizeof(p));
73         dfs(rt,0);
74         printf("%d\n",ans);
75     }
76     return 0;
77 }
View Code

 













埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 B合约数

标签:ack   esc   ext   ons   amp   memset   bubuko   题目   lin   

原文地址:https://www.cnblogs.com/lzhAFO/p/9038500.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!