P1069 细胞分裂(分解质因子)

P1069 细胞分裂

题目描述

给出两个数 m 1 , m 2 m1,m2 m1,m2 n n n个数 s 1 , s 2 , . . . . , s n s_1,s_2,....,s_n s1,s2,....,sn,试在 s i s_i si中选取一个数使得 m 1 m 2 ∣ ( s i ) k m_{1}^{m_2}|(s_i)^{k} m1m2(si)k m 1 m 2 m_{1}^{m_2} m1m2整除 ( s i ) k (s_i)^{k} (si)k)中的 k k k最小. 如果找不到这样的 s i s_i si,输出“ − 1 -1 1”.

题目解析

要求能够整除,说明 m 1 m 2 m_{1}^{m_2} m1m2的所有质因数组成的集合是 ( s i ) k (s_i)^k (si)k的所有质因数组成的集合的子集,而且两者的交集中,交集的元素出现的次数在 ( s i ) k (s_i)^k (si)k中出现得更多.

我们不妨对 m 1 m_1 m1进行质因数分解,而 m 1 m 2 m_{1}^{m_2} m1m2的质因数与 m 1 m_1 m1的质因数相同,只是每个质因数的出现个数 x ∗ m 2 x*m_2 xm2而已. 再对每一个输入的 s i s_i si进行质因数分解,如果 m 1 m_1 m1的所有质因数在 s i s_i si中都有体现,那么 s i s_i si就至少需要 y i = m a x ( ⌈ x ∗ m 2 s u m ⌉ ) y_i=max(\left \lceil \frac{x*m_2}{sum} \right \rceil) yi=max(sumxm2)(其中 s u m sum sum为该质因数在 s i s_i si中出现的次数, x x x为该质因数在 m 1 m_1 m1中出现的次数)次的乘方才行. 将每一次的 y i y_i yi进行比较,输出最小的即可.

代码实现

#include<bits/stdc++.h>
#define maxn 30010
#define ll long long
using namespace std;
int n,m1,m2;
int t,stac[maxn],stac_sum[maxn],p[maxn];
bool vis[maxn];
ll now,minn=0x3f3f3f3f;
void prepare(){
	int op=m1;
	int tot=0;
	for(int i=2;i<=m1;i++){
		if(!vis[i]){
			p[++tot]=i;//素数数组
			if(m1%i==0){
				stac[++t]=i;//m1的质因子数组
				while(op%i==0){
					op/=i;
					stac_sum[t]++;//记录质因子出现次数
				}
				stac_sum[t]*=m2;//质因子翻倍出现
			}
		}
		for(int j=1;j<=tot&&p[j]*i<=m1;j++){
			vis[p[j]*i]=true;
			if(i%p[j]==0)break;//线性筛法
		}
	}
}
int main(){
	scanf("%d",&n);
	scanf("%d%d",&m1,&m2);
	prepare();
	for(int i=1;i<=n;i++){
		ll maxm=0;
		scanf("%lld",&now);
		bool flag=true;
		for(int j=1;j<=t;j++){
			int s=0;
			while(now%stac[j]==0){
				now/=stac[j];
				s++;
			}
			if(s==0){flag=false;break;}//特判,并没有出现所有质因子
			if(stac_sum[j]<s&&maxm==0){maxm=1;continue;}
			ll op=((stac_sum[j]%s==0)?(stac_sum[j]/s):(stac_sum[j]/s+1));//特判向上取整,大于等于这个数的最小整数
			maxm=max(maxm,op);
		}
		if(!flag)continue;
		minn=min(maxm,minn);//s中取最小
	}
	if(minn==0x3f3f3f3f)printf("-1\n");//根本没有满足条件的情况
	else printf("%lld\n",minn);
	return 0;
} 

题后反思

1. 1. 1.对于质因子分解这种思想还不太了解,导致不看标签就没了思路. 以后要多加练习,见到类似的题想一想能不能用质因数分解,尤其是这种整除问题.

2. 2. 2.写挂了好几次这个东西: ( a b ) c = a b ∗ c ≠ a b + c (a^b)^c=a^{b*c}\neq a^{b+c} (ab)c=abc̸=ab+c,说明写题时还是没有完全想清楚.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值