队赛Day2

前置 因子狂热分子

核心在于求数字n!的素数因子i的个数
考虑1-n中所有数字中含有因子i的数字的个数,含有因子2i的数字的个数……
则n/i可得含有因子i的数字个数,n/2i可得含有因子2i的数字的个数……
全部相加,就是n!的素数因子i的个数了
又排列数A(N,M)= N! / (N-M)!
因为当分子分母含有同一个因子时可约
所以A(N,M)含有素数因子i的个数即
【分子含有素数因子i的个数-分母含有素数因子i的个数】

比如说10!有多少个素因子2?
我们一层一层考虑:(数字1到10中)有因子2的数个数+有因子4的数个数+有因子8的数个数+…….
10/2(数字是2,4,6,8,10)+10/2/2(4,8)+10/2/2/2(8)

#include<stdio.h>
#include<iostream>

using namespace std;
typedef long long LL;
//x中有多少个素因子k?
//1-x中有素因子k的数的个数,有素因子2k的数的个数……
const int MOD=1000000007;
LL k;
LL f(LL x){
	LL ans=0;
	while(x){
		ans+=x/k;
		ans%=MOD;
		x/=k;
	}
	return ans;
}
int main()
{
	LL n,m;
	cin>>n>>m>>k;
	LL y=f(n)-f(n-m);
	y=(y%MOD+MOD)%MOD;//这样取模可以避免负数所得结果是负数的问题
	cout<<y;
	return 0;
}

E 因子问题

#include<cstdio>
#include<iostream>
using namespace std;
int cnt[100 + 10];

bool check(int x) {//判断x是否为素数
	for (int i = 2; i < x; i++) {
		if (x % i == 0) return 0;
	}
	return 1;
}

int solve(int x,int k) {//求x中素数因子k的个数
	int num = 0;
	while (x) {
		num += x / k;
		x /= k;
	}
	return num;
}

int main()
{
	//要求i的正因子个数为50
	//由唯一分解定理:i=p1^k1*p2^k2*p3^k3…… 
	//可知i的正因子个数50由式子(k1+1)*(k2+1)*(k3+1)……给出
	//而50=1*50=2*25=10*5=2*5*5共四种情况
	//所以式子有四种情况
	//k1=49
	//k1=1;k2=24
	//k1=9;k2=4
	//k1=1;k2=4;k3=4

	//显然这个i同时符合条件①与②
	//(注意i|(n!)是n!%i==0的意思,由于i就是2-n之间的数字,必定符合
	int n;
	cin >> n;
	//找出2-n之间的素数i,求出n有多少个素数因子i
	for (int i = 2; i <= n; i++) {
		if (check(i)) cnt[i]=solve(n,i);
	}

	long long ans=0;
	for (int i = 2; i <= n; i++) {
		if (cnt[i] >= 49) ans++;
		//n中的素数因子i≥49个
		//有1个符合条件的i
	}
	for (int i = 2; i <= n; i++) {
		if (cnt[i] >= 1) {
			for (int j = 2; j <= n; j++) {
				if (cnt[j] >= 24 && j != i) ans++;
			}
		}
	}
	for (int i = 2; i <= n; i++) {
		if (cnt[i] >= 4) {
			for (int j = 2; j <= n; j++) {
				if (cnt[j] >= 9 && j != i) ans++;
			}
		}
	}
	for (int i = 2; i <= n; i++) {
		if (cnt[i] >= 4) {
			for (int j = i + 1; j <= n; j++) {
				if (cnt[j] >= 4 && j != i) {
					for (int k = 2; k <= n; k++) {
						if (cnt[k] >= 1 && k != j && k != i) ans++;
					}
				}
			}
		}
	}
	cout << ans;
	return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值