第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 B 合约数(启发式合并)

49人阅读 评论(0) 收藏 举报
分类:

链接: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取模后的结果.


解题思路:深搜,枚举每一颗子树,对每一个子树用map维护val的个数,再判断合约数有多少个,然后计算答案即可。深搜时,用启发式合并(小的合并到大的)来维护map,对于所有合约数,先预处理出来。


#include<iostream>
#include<vector>
#include<string.h>
#include<set>
#include<unordered_map>
using namespace std;
typedef long long int ll;
const int MOD=1e9+7;
struct edge{
    int u;
    int v;
    int next;
}e[40005];
int head[20005],edge_num;
void insert_edge(int u,int v){
    e[edge_num].u=u;
    e[edge_num].v=v;
    e[edge_num].next=head[u];
    head[u]=edge_num++;
}
 
int val[20005];
 
ll ans=0;
vector <int> fac[10005];
 
bool is_prime[20005];
void preprocess(int n)
{
    for (int i=2;i<=n;i++)
        is_prime[i]=true;
    for (int i=2;i<=n;i++)
        if (is_prime[i])
            for (int j=i+i;j<=n;j+=i)
                is_prime[j]=false;
    for (int i=2;i<=n;i++)
        if (!is_prime[i])
            for (int j=i;j<=n;j+=i)
                fac[j].push_back(i);
}
 
unordered_map<int,int> mp[20005];
int mn[20005];
 
int merge(int u,int v){
    if(mp[u].size()<mp[v].size()){
        for(auto &j:mp[u]){
                mp[v][j.first]+=j.second;
        }
        return v;
    }
    else{
        for(auto &j:mp[v]){
                mp[u][j.first]+=j.second;
        }
        return u;
    }
}
 
void dfs(int u,int pre){
    for(int i=head[u];i!=-1;i=e[i].next){
        int v=e[i].v;
        if(v!=pre){
            dfs(v,u);
            mn[u]=merge(mn[u],mn[v]);
        }
    }
 
    mp[mn[u]][val[u]]++;
    ll num=0;
    for(auto &i:fac[val[u]])
        num+=mp[mn[u]][i];
    ans=(ans+num*u%MOD)%MOD;
}
 
 
int main(){
    preprocess(10000);
    int T;
    int u,v;
    int N,P;
    scanf("%d",&T);
    while(T--){
        for(int i=0;i<=20002;i++){
            mn[i]=i;
            mp[i].clear();
        }
        ans=0;
        memset(head,-1,sizeof(head));
        edge_num=0;
        scanf("%d%d",&N,&P);
        for(int i=0;i<N-1;i++){
            scanf("%d%d",&u,&v);
            insert_edge(u,v);
            insert_edge(v,u);
        }
        for(int i=1;i<=N;i++)
            scanf("%d",&val[i]);
 
        dfs(P,-1);
        printf("%lld\n",ans);
 
    }
 
    return 0;
}



查看评论

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

B - 合约数 思路: &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;n...
  • hnust_Derker
  • hnust_Derker
  • 2018-04-15 19:06:59
  • 123

埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛A题Wasserstein Distance

题目链接:https://www.nowcoder.com/acm/contest/91/A题意:给两组数据,求把A变成B状态需花费的最小体力。思路:s=s+abs(a[i]-b[i]);a[i+1]...
  • weixin_36416680
  • weixin_36416680
  • 2018-04-15 20:11:56
  • 33

“盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛 M SHUOJ 422 风力观测

给定一个数n(1
  • dpppBR
  • dpppBR
  • 2017-07-10 11:40:37
  • 554

【牛客网】【埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛】L—K序列【动态规划】

题目链接:L—K序列题解:for一遍数组,temp[i]表示:不包括当前for到的点,序列和为i的最长长度。然后for一遍0-k,对dp[ (j+num[i])%k ]进行更新,dp[j]是包括当前点...
  • gymgym1212
  • gymgym1212
  • 2018-04-15 18:46:39
  • 167

【牛客网】【埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛】B—合约数【莫队做法】

题目链接:B—合约数题意:一棵树,有n个节点,从1编号到n。根节点的编号为p。给出每个节点的val[i]值,定义f(i)为以编号i为根节点的子树中(包括根节点),所有val[j]是合数并且是val[i...
  • gymgym1212
  • gymgym1212
  • 2018-04-15 20:33:28
  • 134

1 + 2 = 3 ? 上海五校赛F

链接:https://www.nowcoder.com/acm/contest/91/F题目描述 小Y在研究数字的时候,发现了一个神奇的等式方程,他屈指算了一下有很多正整数x满足这个等式,比如1和2...
  • ummmmm
  • ummmmm
  • 2018-04-15 20:23:20
  • 17

牛客练习赛15 F - 压状Kruskal

题目链接:点击打开链接解题思路:大部分都在注释里,这个复杂度很玄学,应该是可以很强的测试数据,要不然我感觉要凉,感觉这个算法复杂度至少得O(n*(n-(2^(按位算1的个数))))#include&a...
  • a1214034447
  • a1214034447
  • 2018-04-14 21:37:27
  • 16

金马五校赛 I : 二数

题目链接:点击打开链接大意:给定一个十进制下最多105位的数字,请你求出和这个数字的差的绝对值最小的二数,若答案不唯一,输出最小的那个。 也就是说,给定数字n,求出m,使得abs(n-m)最小且...
  • swunHJ
  • swunHJ
  • 2018-04-15 20:19:14
  • 17

埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛 F-1+2=3?

链接:https://www.nowcoder.com/acm/contest/91/F来源:牛客网题目描述 小Y在研究数字的时候,发现了一个神奇的等式方程,他屈指算了一下有很多正整数x满足这个等式...
  • albertluf
  • albertluf
  • 2018-04-15 16:46:44
  • 124

2018年4月15日训练日记

今天还是很有必要总结一下牛客网上的 埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高校金马五校赛。今天发挥失常,仅出了5题,rank100+。比赛:埃森哲杯第十六届上海大学程序设计联赛春季赛暨上海高...
  • LSD20164388
  • LSD20164388
  • 2018-04-15 21:00:41
  • 32
    个人资料
    持之以恒
    等级:
    访问量: 3万+
    积分: 2727
    排名: 1万+
    Visitors
    Flag Counter
    文章分类
    最新评论