zoukankan      html  css  js  c++  java
  • POJ 1091 跳蚤

     1 #include<stdio.h>
     2 int prime[10];      //十个就够了,因为m最多有不超过10个素因子 
     3 long long pow(long long x,int y)//求x^y幂,用大整数 
     4 {
     5     long long res=1;
     6     while(y--)
     7         res*=x;
     8     return res;
     9 }
    10 int main()
    11 {
    12     int i,j,n,m,t,tol=0;
    13     scanf("%d%d",&n,&m);
    14     t=m;
    15     long long res=pow(m,n); //必须用大整数
    16     for(i=2;i*i<=m;i++)//计算素因子个数
    17     {
    18         if(m%i==0)
    19             prime[tol++]=i;
    20         while(m%i==0)
    21             m/=i;
    22     }
    23     if(m!=1)        //如果本身就是大于n开方的素数,需要加一,这点不要忘记
    24         prime[tol++]=m;
    25     for(i=1;i<(1<<tol);i++)//总共有1~2^tol-1个组合
    26     {
    27         int  k=1;
    28         int  sum=0;
    29         for(j=0;j<tol;j++)//巧妙利用二进制来查找到所有素因子组合构成的数
    30         {
    31             if(i&(1<<j))
    32             {
    33                 k*=prime[j];
    34                 sum++;
    35             }
    36         }
    37         if(sum&1) res-=pow(t/k,n);//假如含有素因子个数为奇数,则减去,否则加上
    38         else res+=pow(t/k,n);
    39     }
    40     printf("%lld\n",res);
    41     return 0;
    42 } 

    根据数论的知识
    如果存在x[1],x[2].....x[n],使得 data[1]*x[1]+data[2]*x[2]+......+data[3]*x[3]==1;,则,data[1],data[2],....data[n]最大公约数一定是1;

    一共有 m^n张卡片,如果减去其中含有公约数的卡片剩下的就是所求的结果

    举个例子 n=2, m=360;    360=2^3*3^2*5   

    结果 = (m ^ n) - (有公因数2的n元组)- (有公因数3的n元组)- (有公因数5的n元组)+ (有公因数2,3的n元组) +(有公因数2,5的n元组) + (有公因数3,5的n元组)- (有公因数2,3,5的n元组)。这个比公式形象些有公因数d的n元组,每个位置上有 (m/d)个选择(1 ~ m里面有m/d个d的倍数),根据乘法原理,可以得出有公因数d的n元组有 (m/d)^n 个。

  • 相关阅读:
    软件开发流程实例之四 :编码和测试
    软件开发流程实例之三 :系统设计
    jQuery入门[4]-链式代码
    jQuery入门[1]-构造函数
    jQuery入门[2]-选择器
    自编类库,添加引用,编译运行时显示“未能找到”
    SelectByShape 工具的实现
    TOC控件不显示内容列表
    鹰眼功能的实现(步骤,无代码)
    INumericFormat 接口
  • 原文地址:https://www.cnblogs.com/shihuajie/p/2980709.html
Copyright © 2011-2022 走看看