列表

详情


NC236807. Romantic Misletoe

描述

有什么含义呢?

槲寄生,是属于圣诞前夜的浪漫的花,代表希望和丰饶,也代表爱情。

但是这所代表的和这道题没有任何关系,做出这道题不保证你能度过甜蜜的圣诞,也不能保证你不能度过一个甜蜜的圣诞。不同的是,圣诞节的那天,作为圣诞礼物小 L 给你了一道题目。

小 L 在采购圣诞礼物的时候发现树很有意思。他定义一个 n 个节点的槲寄生树为一个满足如下要求的树:树的每个节点带正整数点权,且满足儿子节点的点权不大于父亲节点的点权,且所有点权的最大公约数为 1,且点权都 。形式化地,即设点权为 d_i,则满足 。其中,树的根节点为 1

因为小 L 正在关注皇家马德里的消息,所以代替他的小 L 给你了一个有 n 个节点的树。不同于小 L,她想知道有多少不同的安排权值的方案使得这个树变成一棵槲寄生树,以便确定是否够送人。因为小 L 的圣诞节还要陪小 L 过,所以你只需要输出方案数对 取余的结果。

输入描述

第一行两个正整数 n,m

后面 n-1 行输入两个正整数 ,表示树上的一条边 u,v

输出描述

一行,一个整数表示方案数。

示例1

输入:

4 2
1 2
2 3
2 4

输出:

5

示例2

输入:

2 4
1 2

输出:

6

示例3

输入:

3 5
1 2
1 3

输出:

48

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 1199ms, 内存消耗: 342116K, 提交时间: 2022-05-19 11:56:05

#include<bits/stdc++.h>

#define int long long

using namespace std;

inline int read(){
    int x=0,f=1;char c=getchar();
    for(;(c<'0'||c>'9');c=getchar()){if(c=='-')f=-1;}
    for(;(c>='0'&&c<='9');c=getchar())x=x*10+(c&15);
    return x*f;
}

#define OK puts("OK")

const int mod=1e9+7;
const int MN=2005;
const int MC=3e7+5;
int n,m;
vector<int>G[MN];
int f[MN][MN],g[MN][MN];

void dp(int u,int fa){
    for(int i=1;i<=n+1;i++)f[u][i]=1;
    for(int v:G[u]){
        if(v==fa)continue;
        dp(v,u);
        for(int i=1;i<=n+1;i++)f[u][i]=f[u][i]*g[v][i]%mod;
    }
    for(int i=1;i<=n+1;i++)g[u][i]=(g[u][i-1]+f[u][i])%mod;
}

int a[MN],invx[MN],p[MN],q[MN],r[MN];

int ksm(int x,int y,int p=mod){
    int res=1;
    for(int i=y;i;i>>=1,x=x*x%p)if(i&1)res=res*x%p;
    return res;
}

int inv(int x,int p=mod){
    return ksm(x,p-2,p);
}

void Lagrange(){
    for(int i=1;i<=n+1;i++)invx[i]=inv(i);
    p[0]=1;
    for(int i=1;i<=n+1;i++){
        q[0]=mod-i,q[1]=1;
        for(int j=0;j<i;j++)
            for(int k=0;k<=1;k++)r[j+k]=(r[j+k]+p[j]*q[k]%mod+mod)%mod;
        for(int j=0;j<=i;j++)p[j]=r[j],r[j]=0;
    }
    for(int i=1;i<=n+1;i++){
        int fm=inv(g[1][i])%mod;
        for(int j=1;j<=n+1;j++)if(j!=i)fm=fm*(i-j+mod)%mod;
        r[0]=(mod-p[0]*invx[i]%mod+mod)%mod,fm=inv(fm);
        for(int j=1;j<=n;j++)r[j]=(mod-(p[j]-r[j-1]+mod)%mod*invx[i]%mod+mod)%mod;
        for(int j=0;j<=n;j++)a[j]=(a[j]+r[j]*fm%mod+mod)%mod;
    }
}

int calc(int k){
    int res=0;
    for(int i=n;i>=0;i--)res=(res*k%mod+a[i])%mod;
    return res;
}

int mu[MC],pri[1857860];
bool isp[MC];

void pre(){
    int N=30000000,cnt=0;mu[1]=1;
    memset(isp,1,sizeof(isp));
    for(int i=2;i<=N;i++){
        if(isp[i])pri[++cnt]=i,mu[i]=-1;
        for(int j=1;j<=cnt;j++){
            if(i*pri[j]>N)break;
            int x=i*pri[j];isp[x]=0;
            if(i%pri[j]==0){mu[x]=0;break;}
            mu[x]=-mu[i];
        }
    }
    for(int i=1;i<=N;i++)mu[i]+=mu[i-1];
}

signed main(void){


    n=read(),m=read();
    for(int i=1;i<=n-1;i++){
        int u=read(),v=read();
        G[u].push_back(v),G[v].push_back(u);
    }
    dp(1,0);pre(),Lagrange();
    int ans=0;
    for(int l=1,r=0;l<=m;l=r+1){
        r=m/(m/l);
        ans=(ans+(mu[r]-mu[l-1]+mod)%mod*calc(m/l)%mod+mod)%mod;
    }
    cout<<ans<<endl;


    return 0;
}

上一题