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

posted on   小花熊  阅读(506)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
< 2013年3月 >
24 25 26 27 28 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 1 2 3 4 5 6

导航

统计

点击右上角即可分享
微信分享提示