Codeforces Round 948 (Div. 2) C题 Nikita and LCM

题意:给定一个正整数序列a,问满足序列lcm不在a中的最长序列长度

这种题拿着很棘手,就感觉无从下手,后面感觉有很多题都是从答案的角度去考虑问题。

可以发现,lcm一定大于等于该序列的最大值,整个序列的lcm是很容易不在这个序列的。

假设lcm不在这个序列,那么一定存在一个数字使得最大值%x不=0,答案为n

假设整个序列lcm等于最大值,那么可以说明所有数字都是最大值的因数,所以所有子序列的lcm也一定是最大值的因数,考虑对最大值做分解,枚举答案,我们发现假设当前答案为x,只要x%序列的某个值==0,那么把序列的这个加进来是一定最优的,所以我们尽量把所有数字都加进来,最后算一下lcm是否跟当前枚举的答案一样即可更新答案

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
#define int  long long 
typedef pair<int, int>pii;
typedef pair<int, double>pid;
typedef pair<pii, int>piii;
const int mod = 998244353;
const int N = 1e6 + 100;
int poww(int a, int b) { if (a == 0 && b == 0)return 1; int ans = 1; for (int i = 1; i <= b; i++)ans = ans * a; return ans; }
int sqrtt(int x) { int l = 0, r = 3e9; while (l < r) { int mid = (l + r + 1) >> 1; if (mid * mid == x)return mid; else if (mid * mid > x)r = mid - 1; else l = mid; }return l; }

int a[N];
int n;
int ck(int val)
{
	int lcmm = 1;
	int cnt = 0;
	for (int i = 1; i <= n; i++)
		if (val % a[i] == 0)cnt++, lcmm = lcm(lcmm, a[i]);
	if(lcmm==val)
	return cnt;
	return 0;
}

void solve()
{
	cin >> n;

	map<int, int>st;
	for (int i = 1; i <= n; i++)
	{
		cin >> a[i]; st[a[i]] = 1;
	}
		sort(a + 1, a + 1 + n);
	for (int i = 1; i < n; i++)
	{
		if (a[n] % a[i])
		{
			cout << n << endl;
			return;
		}
	}

	if (a[n] == 1)cout << 0 << endl;
	else
	{
		int ans = 0;
		for (int i = 2; i * i <= a[n]; i++)
		{
			if (a[n] % i == 0)
			{
				if(st.count(i)==0)
				ans = max({ ck(i),ans });
				if (st.count(a[n] / i) == 0)
				{
					ans = max({ ck(a[n]/i),ans });
				}
			}
		}
		cout << ans << endl;
	}

}


signed main()
{
	ios::sync_with_stdio(0); cout.tie(0); cin.tie(0);
	int t = 1;
	cin >> t;
	while (t--)solve();
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值