zoukankan      html  css  js  c++  java
  • POJ 3904 Sky Code

     1 #include<iostream>
     2 #include<cstdlib>
     3 #include<stdio.h>
     4 #include<string.h>
     5 #define MAX 10005
     6 using namespace std;
     7 int cnt[MAX],num[MAX],prime[MAX];
     8 long long  p[MAX]; //必须用大整数 
     9 void Solve(int  n)
    10 {
    11     int i,j,tol=0;
    12     for(i=2;i*i<=n;i++)//计算素因子个数 
    13     {
    14         if(n%i==0)
    15         {
    16             prime[tol++]=i;
    17         }
    18         while(n%i==0)
    19             n/=i;
    20     }
    21     if(n!=1)        //如果本身就是大于n开方的素数,需要加一,这点不要忘记 
    22     prime[tol++]=n;
    23     for(i=1;i<(1<<tol);i++)//总共有1~2^tol-1个组合 
    24     {
    25         int  k=1;
    26         int  sum=0;
    27         for(j=0;j<tol;j++)//巧妙利用二进制来查找到所有素因子组合构成的数 
    28         {
    29             if(i&(1<<j))
    30             {
    31                 k*=prime[j];
    32                 sum++;
    33             }
    34         }
    35         cnt[k]++; //记录含有因子K的数的个数 
    36         num[k]=sum;    //记录k中含有素因子的个数 
    37     }
    38 }
    39 int main()
    40 {
    41    int m,n;
    42    long long i; 
    43    memset(p,0,sizeof(p));
    44    memset(num,0,sizeof(num));
    45    for(i=4;i<MAX;i++)        //先打表,提高效率,i<4时p[i]为0; 
    46         p[i]=i*(i-1)*(i-2)*(i-3)/24;
    47    while(~scanf("%d",&n))
    48    {
    49        memset(cnt,0,sizeof(cnt));
    50        for(i=0;i<n;i++)
    51        {
    52            scanf("%d",&m);
    53            Solve(m);        //求解其素因子,并统计相关数据 
    54        }
    55        long long ans=0;
    56        for(int  i=0;i<MAX;i++)
    57        {
    58            if(cnt[i]>=4)//剪枝,必须大于等于四  
    59            {
    60                if(num[i]&1) //假如含有素因子个数为奇数,则加上;否则减去 
    61                     ans+=p[cnt[i]];
    62                else
    63                        ans-=p[cnt[i]];
    64            }
    65        }
    66        cout<<p[n]-ans<<endl; //最后用总的减去不符合的四元组个数 
    67    }
    68 }

    思路:容斥原理,把每个数素数分解,记录不重复素因子所能组成的因子,把这些因子的总数统计,并且统计每个因子是由多少个素因子组成  
    如这n个数中含2的个数为a,含3的个数为b,含6的个数为c,那么公约数大于1的总数为p=c(a,4)+c(b,4)-c(c,4),总的个数为c(n,4)  
    用c(n,4)-p即为所求

  • 相关阅读:
    JAVA多线程知识点
    RabbitMQ和Springboot集成RabbitMQ知识点
    JAVA动态代理cglib或jdk
    [转]解决System.Data.SqlClient.SqlException (0x80131904): Timeout 时间已到的问题的一个方向
    [转]C#判断文档编码格式,并读取文档数据(防止出现乱码)
    create_linux命令写入到sh脚本并删除
    cmd cd切换到d盘
    sql 优化前后
    LISTAGG()WITHIN GROUP()
    使用shell递归遍历文件并打印所有文件名的绝对路径
  • 原文地址:https://www.cnblogs.com/shihuajie/p/2980456.html
Copyright © 2011-2022 走看看