[CF632D] Longest Subsequence - 埃氏筛
Description
给出 n 个数,要求选出尽可能多的数,满足它们的最小公倍数不大于 m (\(\le 10^6)\)。允许数列里没数,此时这个数列的最小公倍数为 1。
Solution
可以转化为,选出最多的数,使得他们存在一个公倍数不大于 m
统计对于 1..m,每个 i 在给定数中的因子数量,这个因子数量对应的就是令公倍数为 i 时能选出的最大集合
所以问题转化为,对每个 1..m,统计给定数中有多少个是它的因子,类似埃筛
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1000005;
int n, m, a[N], cnt[N], f[N];
signed main()
{
ios::sync_with_stdio(false);
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i <= n; i++)
if (a[i] <= m)
cnt[a[i]]++;
for (int i = 1; i <= m; i++)
for (int j = i; j <= m; j += i)
f[j] += cnt[i];
int ans = 1;
for (int i = 1; i <= m; i++)
if (f[i] > f[ans])
ans = i;
cout << ans << " " << f[ans] << endl;
for (int i = 1; i <= n; i++)
if (ans % a[i] == 0)
cout << i << " ";
}