TG5 防疫工作安排

题目描述

爆发肺炎疫情的H省共有 n 个地级市,为了最大限度减缓疾病蔓延,这些地级市用 1 到 n 开始编号,由 n−1 条道路相连,并且保证联通。统筹疫情防控的省会W市为根节点,编号为 1 .

为了防疫,首先需要给每个地级市安排一个重要度。具体来说,对于每个市,它的重要度是 [1,m] 中的一个整数(可以重复)。同时有一个特殊的要求:对于从根节点到叶子节点的每一条路径,路径上所有数字的最大公约数必须为 1 .

现在你需要求出合法的重要度安排方法的数量。答案对 10^9+7 取模。

输入格式

第一行两个整数 n,m ,意义如题所示。

接下来 n−1 行,每行两个整数 u,v ,表示一条道路。

输出格式

一行一个整数,表示答案

【数据范围与约定】

……

对于 100% 的数据,满足 1≤n≤10^5,1≤m≤20

观察数据范围,发现m很小,而20以下的质数有8个

dp[i][j]表示i点的子树中,二进制j代表的质数满足下列条件

满足条件的意思是,这个点向下到叶子的每一条路径都至少有一个点不含这个质数

也就是上面的位置可以填含有这个质数的数

大量冗余状态,使用记忆化搜索,需要求的是dp[1][255],每次枚举当前填写的数字,得到对孩子的j的要求,然后将各个孩子方案数相乘。

具体实现以代码注释的方式呈现

Talk is cheap,shou me the code

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 #define mod 1000000007
 4 using namespace std;
 5 int n,m,f[25],p[8]={2,3,5,7,11,13,17,19};
 6 ll dp[257][100005];
 7 vector<int> g[100005];
 8 ll dfs(int now,int fa,int mask){
 9     if(dp[mask][now]!=-1)//可能重复访问的节点,进行记忆化搜索 
10       return dp[mask][now];
11   ll res=0;
12   for(int i=1;i<=m;i++){
13     if(g[now].size()==1&&now!=1)
14       res += !(mask&f[i]);//叶节点填i是否为合法方案,如果是方案数加一,否则加零(非运算特性) 
15         else{
16             ll t=1;
17             for(int j=0;j<g[now].size();j++){
18                 int to=g[now][j];
19                 if(to==fa)continue;
20                 t=t*dfs(to,now,mask&f[i])%mod;//枚举子节点并待回溯后计算答案,更新孩子所需满足的条件
21                                                                             //1:                                                                                                                 
22             }
23             res=(res+t)%mod;//某节点上i被选择的情况下对答案的贡献 
24         }
25     }
26     return dp[mask][now]=res;//更新dp值并回溯 
27 }
28 int main(){
29     cin>>n>>m;
30     for(int i=1;i<=n-1;i++){
31         int u,v;
32         cin>>u>>v;
33         g[u].push_back(v);
34         g[v].push_back(u);
35     }
36     for(int i=1;i<=20;i++)
37       for(int j=0;j<8;j++)
38           if(!(i%p[j]))
39             f[i] |= 1<<j;//预处理i有哪些质因子 ,便于转移 
40     memset(dp,-1,sizeof(dp));
41     cout<<dfs(1,0,255);
42     return 0;    
43 }
View Code

猜你喜欢

转载自www.cnblogs.com/vv123/p/12334099.html