upc 要塞任务 数论

要塞任务
时间限制: 1 Sec 内存限制: 128 MB

题目描述
你的要塞⾥有N名随从,每名随从有⼀个战⽃⼒值Ai,不同随从的战⽃⼒可以相同,且永远不超过N。⼀个要塞任务需要恰好M个随从参与。
要塞任务的奖励取决于随从们配合的程度。(显⽽易见地),M个随从的联合战⽃⼒A为它们战⽃⼒的最⼤公约数,⽽任务的奖励分数定义为ϕ(A)。
求最⼤可能的奖励分数。
输入
本题有多组数据,第⼀⾏为数据组数T(T≤10)。
接下来每组数据有两⾏,第⼀⾏两个整数N,M,第⼆⾏N个整数Ai(N,M,Ai≤100000)。
输出
最多的奖励分数。
样例输入 Copy
1
5 2
1 4 6 9 12
样例输出 Copy
2
提示
样例解释:派出编号为6和12的随从,联合战⽃⼒为3,奖励分数2。

这个题有两个要求的点,一个是预处理欧拉函数,在有限的时间复杂度内求出 k 个数的最大公约数。
对于第一个,预处理 1 ~ 1e5 的欧拉函数时间完全够用。
对于第二个,一开始sblj的去求每个数的约数让后开个哈希数组记录个数,果不其然就超时了。既然枚举数找出因子不行,那么可以试试枚举因子找数。对于 1 ~ mx 的每个数,依次枚举以它为因子的数,如果枚举到了 a 中的数,那么 cnt ++ ,当cnt >= m 的时候符合条件。也不是很会算时间复杂度,反正这样就能水过去了。。

#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
using namespace std;

typedef long long LL;
typedef pair<int,int> PII;

const int N=100010,mod=1e9+7,INF=0x3f3f3f3f;
const double eps=1e-6;

int n,m;
int a[N],has[N];
LL euler[N];

LL get_ol(int x)
{
    LL res=x;
    for(int i=2;i<=x/i;i++)
        if(x%i==0)
        {
            res=res*(i-1)/i;
            while(x%i==0)
                x/=i;
        }
    if(x>1) res=res*(x-1)/x;
    return res;
}

void init()
{
	for(int i=1;i<=1e5+5;i++)
		euler[i]=get_ol(i);
}

int main()
{
//	ios::sync_with_stdio(false);
//	cin.tie(0);
	
	init();
	
	int t; cin>>t;
	while(t--)
	{
		memset(has,0,sizeof has);
		scanf("%d%d",&n,&m);
		int mx=0;
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&a[i]);
			has[a[i]]++;
			mx=max(mx,a[i]);
		}
		LL ans=0;
		for(int i=1;i<=mx;i++)
		{
			if(ans>=euler[i]) continue;
			LL sum=0;
			for(int j=i;j<=mx;j+=i)
			{
				sum+=has[j];
				if(sum>=m) break;
			}
			if(sum>=m) ans=max(euler[i],ans);
		}
		printf("%lld\n",ans);
	}





	return 0;
}
/*

*/









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值