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

题目链接:http://codeforces.com/problemset/problem/449/C

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

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

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

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 1e5 + 5;
 4 bool prime[N] , vis[N];
 5 int p[N / 3];
 6 vector <int> G[N];
 7 
 8 void init() {
 9     int index = 0;
10     prime[1] = true;
11     for(int i = 2 ; i < N ; ++i) {
12         if(!prime[i]) {
13             p[++index] = i;
14             for(int j = i * 2 ; j < N ; j += i)
15                 prime[j] = true;
16         }
17     }
18 }
19 
20 int main()
21 {
22     init();
23     int n;
24     scanf("%d" , &n);
25     if(n < 4) {
26         printf("0\n");
27         return 0;
28     }
29     int cnt = 0;
30     for(int i = 2 ; p[i] * 2 <= n ; ++i) {
31         for(int j = p[i] ; j <= n ; j += p[i]) {
32             if(!vis[j]) {
33                 vis[j] = true;
34                 G[p[i]].push_back(j);
35             }
36         }
37         if(G[p[i]].size() >= 3 && (G[p[i]].size() % 2))
38             G[2].push_back(p[i] * 2);
39         cnt += G[p[i]].size() / 2;
40     }
41     for(int i = 2 ; i <= n ; i += 2) {
42         if(!vis[i])
43             G[2].push_back(i);
44     }
45     cnt += G[2].size() / 2;
46     printf("%d\n" , cnt);
47     for(int i = 1 ; i < G[2].size() ; i += 2)
48         printf("%d %d\n" , G[2][i - 1] , G[2][i]);
49     for(int i = 2 ; p[i] * 2 <= n ; ++i) {
50         if(G[p[i]].size() % 2) {
51             printf("%d %d\n" , G[p[i]][0] , G[p[i]][2]);
52             for(int j = 4 ; j < G[p[i]].size() ; j += 2)
53                 printf("%d %d\n" , G[p[i]][j - 1] , G[p[i]][j]);
54         }
55         else {
56             for(int j = 1 ; j < G[p[i]].size() ; j += 2)
57                 printf("%d %d\n" , G[p[i]][j - 1] , G[p[i]][j]);
58         }
59     }
60     return 0;
61 }

 

posted @ 2016-07-11 14:31  Recoder  阅读(215)  评论(0编辑  收藏  举报