您的位置:首页 > 移动开发

Codeforces Round #257 (Div. 1) C. Jzzhu and Apples (素数筛)

2016-07-11 14:31 369 查看
题目链接:http://codeforces.com/problemset/problem/449/C

给你n个数,从1到n。然后从这些数中挑选出不互质的数对最多有多少对。

先是素数筛,显然2的倍数的个数是最多的,所以最后处理。然后处理3,5,7,11...的倍数的数,之前已经挑过的就不能再选了。要是一个素数p的倍数个数是奇数,就把2*p给2

的倍数。这样可以满足p倍数搭配的对数是最优的。最后处理2的倍数就行了。

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
bool prime
, vis
;
int p[N / 3];
vector <int> G
;

void init() {
int index = 0;
prime[1] = true;
for(int i = 2 ; i < N ; ++i) {
if(!prime[i]) {
p[++index] = i;
for(int j = i * 2 ; j < N ; j += i)
prime[j] = true;
}
}
}

int main()
{
init();
int n;
scanf("%d" , &n);
if(n < 4) {
printf("0\n");
return 0;
}
int cnt = 0;
for(int i = 2 ; p[i] * 2 <= n ; ++i) {
for(int j = p[i] ; j <= n ; j += p[i]) {
if(!vis[j]) {
vis[j] = true;
G[p[i]].push_back(j);
}
}
if(G[p[i]].size() >= 3 && (G[p[i]].size() % 2))
G[2].push_back(p[i] * 2);
cnt += G[p[i]].size() / 2;
}
for(int i = 2 ; i <= n ; i += 2) {
if(!vis[i])
G[2].push_back(i);
}
cnt += G[2].size() / 2;
printf("%d\n" , cnt);
for(int i = 1 ; i < G[2].size() ; i += 2)
printf("%d %d\n" , G[2][i - 1] , G[2][i]);
for(int i = 2 ; p[i] * 2 <= n ; ++i) {
if(G[p[i]].size() % 2) {
printf("%d %d\n" , G[p[i]][0] , G[p[i]][2]);
for(int j = 4 ; j < G[p[i]].size() ; j += 2)
printf("%d %d\n" , G[p[i]][j - 1] , G[p[i]][j]);
}
else {
for(int j = 1 ; j < G[p[i]].size() ; j += 2)
printf("%d %d\n" , G[p[i]][j - 1] , G[p[i]][j]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: