• 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 个。

  • 相关阅读:
    Mysql字段约束
    MYSQL中数据类型介绍
    Redis常见的几种使用方式及其优缺点
    python解析jason串,数据存入数据库
    redo log
    Oracle控制文件(Control Files)
    笔记
    redis面试题
    mysqldump备份
    超简单的内网穿透技巧(使用花生壳进行内网穿透)
  • 原文地址:https://www.cnblogs.com/shihuajie/p/2980709.html
Copyright © 2020-2023  润新知