AtCoder Beginner Contest 177 E Coprime 线性筛素数+统计质因数数量+特判

AtCoder Beginner Contest 177   比赛人数9636

AtCoder Beginner Contest 177   E   Coprime   线性筛素数+统计质因数数量+特判

总目录详见https://blog.csdn.net/mrcrack/article/details/104454762

在线测评地址https://atcoder.jp/contests/abc177/tasks/abc177_e

题目大意:给定一个数组,若其中任意两个元素,两两互质,输出pairwise coprime,若做不到两两互质,但能做到所有元素最大公约数是1,输出setwise coprime, 若所有元素最大公约数不是1,输出not coprime。

基本思路:请看样例模拟过程:

3
3 4 5
pairwise coprime

3=3,4=2^2(2^2,算2在4中出现1次),5=5
质因数出现1次的有3,2,5


3
6 10 15
setwise coprime

6=2*3,10=2*5,15=3*5
质因数出现2次的有2,3,5


3
6 10 16
not coprime

6=2*3,10=2*5,16=2^4(2^4,算2在16中出现1次)
质因数出现1次的有3,5
质因数出现3次的有2

若自觉的算法没有问题,但代码一直无法AC,那么,该题需特判的例子提供给大家

Input:
5
4 9 25 49 121
Output:
pairwise coprime


Input:
5
1 1 1 1 1
Output:
pairwise coprime

AC代码如下:

#include <cstdio>
#include <algorithm>
#define maxn 1000010
using namespace std;
int a[maxn],prime[maxn],not_prime[maxn],tot,vis[maxn];
void linear_shaker(int x){//线性筛素数
	int i,j;
	for(i=2;i<=x;i++){
		if(!not_prime[i])prime[++tot]=i;//prime[i]=j表示第i个质数是j
		for(j=1;prime[j]*i<=x;j++){
			not_prime[i*prime[j]]=prime[j];//此处用了技巧,记录了合数i*prime[j]的最小质因数prime[j]
			if(i%prime[j]==0)break;
		}
	}
}
int main(){
	int n,i,m=0,b,c,cnt=0;//cnt统计质因数最大出现次数
	scanf("%d",&n);
	for(i=1;i<=n;i++)scanf("%d",&a[i]),m=max(m,a[i]);//m找出最大a[i]值,减轻线性筛素数的运算量。
	linear_shaker(m);
	for(i=1;i<=n;i++){
		b=a[i];
		while(not_prime[b]){
			c=not_prime[b];
			vis[c]++,cnt=max(cnt,vis[c]);//vis[c]统计质因数c出现次数
			while(b%c==0)b/=c;//处理2^4这种形式
		}
		if(b!=1)vis[b]++,cnt=max(cnt,vis[b]);//注意此处条件if(b!=1),若没有此句,该题要不断的WA
	}
	if(cnt<=1)printf("pairwise coprime\n");//注意此处条件if(cnt<=1),若没有此句,该题要不断的WA,若数组中元素全是1,cnt==0
	else if(cnt<n)printf("setwise coprime\n");
	else printf("not coprime\n");//cnt>=n
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值