P9836 种树

容易想到分解因数。

对于一个数 ppp 的因数个数,假设它可以被分解质因数成 a1i1a2i2a3i3⋯akcka_1^{i_1} a_2^{i_2} a_3^{i_3}\cdots a_k^{c_k}a1i1a2i2a3i3akck 的形式,则其因数个数为 (i1+1)(i2+1)(i3+1)⋯(ik+1)(i_1+1)(i_2+1)(i_3+1)\cdots(i_k+1)(i1+1)(i2+1)(i3+1)(ik+1)

我们对序列 pppwww 质因数分解之后再考虑这个问题。对于每次从 www 拆分出的一个质因子 AAA,我们假设一棵树 pip_ipi,原来它的贡献为 xxx,对于该棵树高的质因数拆分中质因子 AAA 的出现次数为 ttt,则乘上该质因子之后它的贡献会变为 x⋅t+2t+1x\cdot \dfrac{t+2}{t+1}xt+1t+2,容易证明分子越小即 ttt 越小对答案的贡献越大。

由于数据范围是 10410^4104,质因数的上界是很有限的。设 a(i,j)a(i,j)a(i,j) 表示 iji^jij 在所有树高的质因数拆分中出现了多少次,每一次取到的一个 www 的质因子 AAA,把它计算到当前存在且 kkk 最小的 AkA^kAk 上即可。

注意筛 nnn 的质因数要筛到 nnn

#include <bits/stdc++.h>
using namespace std;
#define int long long

const int maxn=1e4+5;
int a[maxn][30],ans=1,p[maxn],mod=998244353,n,w;

void calc(int x)
{
	for(int i=2;i<=max(x,w);i++)
	{
		int cnt=0;
		while(x%i==0) x/=i,cnt++;
		a[i][cnt]++;
		ans=ans*(cnt+1)%mod;
		// cout<<cnt<<endl;
	}
}

signed main()
{
	cin>>n>>w;
	for(int i=1;i<=n;i++) cin>>p[i],calc(p[i]);
	// for(int i=1;i<=n;i++) cout<<a[i][1]<<endl;
	for(int A=2;A<=w;A++)
		while(w%A==0)
		{
			int k=0;
			while(!a[A][k]) k++;	
			ans/=(k+1),ans%=mod,ans*=(k+2),ans%=mod;
			w/=A,a[A][k]--,a[A][k+1]++;
			// cout<<w<<endl;
		}	
	cout<<ans;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值