CF-1333F Kate and imperfection
F. Kate and imperfection
假设一个一个的往集合里面放元素,显然在放某个元素之前,我们不想让它的倍数已经在集合里面。因为在这之前,我们不如先把这个数放进去,再把它的倍数放进去更优(因为它的倍数更容易和别的数字产生更大的gcd)。
所以在放元素时,这个元素的所有因数应该已经都在集合中了,对于一个集合,如果对于集合中的所有数字,他们的因数都在该集合中,那么这个集合中某两个数字的最大gcd即为某个数的最大真因子(非本身)。
设 \(d[x]\) 为 x 的最大真因数,按照\(d[x]\) 排序处理即可
如果第一段猜想解释还不够清楚,可以参考一下官方题解,首先知道答案序列一定是不降的,分段递增。然后如果对于\(a_i \in A=\{a_1,a_2,\cdots a_k\}\),如果 \(a_i\) 的某个因子不在集合中,可以用这个因子替换掉 \(a_i\) ,这个集合的不完美度只会降低不会升高,所以我们有理由让\(a_i\) 的所有因子都出现在该集合中。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
#define dbg(x...) do { cout << "\033[32;1m" << #x <<" -> "; err(x); } while (0)
void err() { cout << "\033[39;0m" << endl; }
template<class T, class... Ts> void err(const T& arg,const Ts&... args) { cout << arg << " "; err(args...); }
const int N = 500000 + 5;
int primes[N], v[N], m;
void prime(int n){
v[1] = 1;
for(int i=2;i<=n;i++){
if(!v[i]) primes[++m] = i, v[i] = 1;
for(int j=1;j<=m;j++){
if(primes[j] > n / i) break;
v[primes[j]*i] = i;
if(i % primes[j] == 0) break;
}
}
}
int main(){
int n;scanf("%d", &n);
prime(n);
sort(v+1, v+1+n);
for(int i=2;i<=n;i++)
printf("%d ", v[i]);
return 0;
}
注:转载请注明出处