POJ 3421 X-factor Chains 题解

POJ

solve

  • 考虑第一个询问,观察到要求的序列可以通过一个约数乘乘乘构造出,那么最长的就为 x 的所有素约数个数
    • 举例:\(100->2,2,5,5\)
    • 序列:\(2,2 \times 2 = 4,2 \times 2 \times 5 = 20,2 \times 2 \times 5 \times 5 = 100\)
  • 手法bf分解就行
  • 考虑第二个询问,由于我们已经处理出所有素约数,那么就像如下问题

有a个1球,b个2球,c个3球,求将所有球排成一排的方案数

  • 即重排列问题
  • 公式有:\(A(n,n) \div (A(a,a) \times A(b,b) \times A(c,c))\)

code

点击查看代码
#include<bits/stdc++.h>
using namespace std;
constexpr int maxn=1e6+10,p=1e9+7;
long long read() {long long x=0,f=1;char ch=getchar();while (ch<'0' || ch>'9'){if (ch=='-') f=-1;ch=getchar();}while (ch>='0' && ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
long long x;
long long fu[maxn],tot,mi[maxn];
bool pri(long long n)
{
	if (n<=1) return 0;
	for (long long i=2;i*i<=n;i++) if (n%i == 0) return 0;
	return 1;
}
void func(long long n)
{
	for (long long i=2;i*i<=n;i++) if (n%i == 0) {fu[++tot]=i;int cnt=0;while (n%i == 0) n/=i,cnt++;mi[tot]=cnt;}
	if (n>1) fu[++tot]=n,mi[tot]=1;
}
long long getA(long long x,long long y)
{
	long long res=1;
	for (int i=x-y+1;i<=x;i++) res*=i;
	return res;
}
int main()
{
	while (scanf("%lld",&x)!=EOF)
	{
		tot=0;func(x);
		long long ans=0;
		for (int i=1;i<=tot;i++) ans+=mi[i];
		printf("%lld ",ans);
		if (pri(x)) {puts("1");continue;}
		ans=getA(ans,ans);
		for (int i=1;i<=tot;i++) ans/=getA(mi[i],mi[i]);
		printf("%lld\n",ans);
	}
	return 0;
}
posted @ 2026-07-04 10:15  msjing  阅读(9)  评论(0)    收藏  举报