POJ 3904 Sky Code [数学]

  在10^4方内选4个数,这4个数的最大公约数是1,求方案数。

  先求出所有这样的数x=p1*p2*p3..*pn,pi是不同的素数,并且d(x)=n。然后容斥原理即可 ans=C(n,4)+∑C(x,4)*(-1)^d(x)。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 #define MAXN 10005
 5 using namespace std;
 6 typedef long long LL;
 7 int flg[MAXN], x[MAXN], maxx;
 8 LL c[MAXN][5];
 9 void init(){
10     memset(flg ,-1, sizeof flg);
11     for (int i = 2; i < MAXN; i++) if (flg[i] == -1) {
12         for (int j = i; j < MAXN; j += i) {
13             if(flg[j] == -1) flg[j] = 1;
14             else if (flg[j]) ++flg[j];
15             if(j % (i * i) == 0) flg[j] = 0;
16         }
17     }
18     for (int i = 0; i < MAXN; c[i++][0] = 1) {
19         for(int j = 1; j < 5 && j <= i; j++)
20             c[i][j] = c[i-1][j-1] + c[i-1][j];
21     }
22 }
23 int n, tx;
24 int main(){
25     //freopen("test.in", "r", stdin);
26     init();
27     while (scanf("%d", &n) != EOF) {
28         memset(x, 0, sizeof x);
29         maxx = 0;
30         for (int i = 1; i <= n; i++) {
31             scanf("%d", &tx);
32             maxx = max(maxx, tx);
33             for (int j = 1; j * j <= tx; j++) {
34                 if (tx%j==0) {
35                     x[j]++;
36                     if (j*j!=tx) x[tx/j]++;
37                 }
38             }
39         }
40         LL ans = c[n][4];
41         for (int i = 2; i <= maxx; i++) {
42             if (flg[i] == 0) continue;
43             if (flg[i]&1) ans -= c[x[i]][4];
44             else ans += c[x[i]][4];
45         }
46         printf("%lld\n",ans);
47 
48     }
49 
50     return 0;
51 }
posted @ 2012-10-31 16:50  Burn_E  阅读(239)  评论(0编辑  收藏  举报