zoukankan      html  css  js  c++  java
  • hdu 5072 Coprime

    http://acm.hdu.edu.cn/showproblem.php?pid=5072

    题意:给出 n 个互不相同的数,求满足以下条件的三元无序组的个数:要么两两互质要么两两不互质。

    思路:根据同色三角形原理求,白书105页。求它不符合条件的情况数,先对每一个数分解质因子,然后利用容斥求出与这个数不互质的数的个数,那么不符合条件的的情况数加上(x-1)*(n-x);  x为其它数与这个数不互质的个数。最后总的情况数减去不符合的情况数,剩下的就是答案。再求多少个是这个数的倍数的时候,可以用筛法求出。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <vector>
     4 #include <algorithm>
     5 #define maxn 100010
     6 using namespace std;
     7 
     8 int t,n;
     9 int a[maxn+10];
    10 int num[maxn+10];
    11 int cnt[maxn+10];
    12 vector<int>g;
    13 
    14 int main()
    15 {
    16     scanf("%d",&t);
    17     while(t--)
    18     {
    19         memset(cnt,0,sizeof(cnt));
    20         memset(num,0,sizeof(num));
    21         scanf("%d",&n);
    22         for(int i=0; i<n; i++)
    23         {
    24             scanf("%d",&a[i]);
    25             num[a[i]]++;
    26         }
    27         for(int i=1; i<=maxn; i++)
    28         {
    29             for(int j=i; j<=maxn; j+=i)
    30             {
    31                 cnt[i]+=num[j];
    32             }
    33         }
    34         __int64 ans=0;
    35         for(int i=1; i<maxn; i++)
    36         {
    37             if(num[i])
    38             {
    39                 int m=i;
    40                 g.clear();
    41                 for(int j=2; j*j<=i; j++)
    42                 {
    43                     if(m%j==0)
    44                     {
    45                         g.push_back(j);
    46                         while(m%j==0) m/=j;
    47                     }
    48                 }
    49                 if(m>1) g.push_back(m);
    50                 int x=(int) g.size();
    51                 int cc=0;
    52                 for(int j=1; j<(1<<x); j++)
    53                 {
    54                     int t2=0;
    55                     int xx=1;
    56                     for(int k=0; k<x; k++)
    57                     {
    58                         if((1<<k)&j)
    59                         {
    60                             t2++;
    61                             xx*=g[k];
    62                         }
    63                     }
    64                     if(t2%2) cc+=cnt[xx];
    65                     else  cc-=cnt[xx];
    66                 }
    67                 ans+=(__int64)max(cc-1,0)*(n-cc);
    68             }
    69         }
    70         __int64 t1=(__int64)n*(n-1)*(n-2)/6;
    71         printf("%I64d
    ",t1-ans/2);
    72     }
    73     return 0;
    74 }
    View Code
  • 相关阅读:
    ZOJ4125 Sekiro
    ZOJ4118 Stones in the Bucket
    ZOJ4115 Wandering Robot
    ZOJ4113 Calandar
    【递归】N皇后问题 和 2n皇后问题 dfs
    7-18
    7_13
    二维前缀和
    64位整数乘法
    【分治】魔法石的诱惑
  • 原文地址:https://www.cnblogs.com/fanminghui/p/4235248.html
Copyright © 2011-2022 走看看