您的位置:首页 > 其它

HDU 2204 Eddy's爱好(容斥原理)

2014-07-26 16:54 267 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2204

解题报告:输入一个n让你求出[1,n]范围内有多少个数可以表示成形如m^k的样子。

不详细说了,自己一开始也忽略了三个素数的乘积的乘方的情况。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long INT;
INT prim[70];

int dabiao()
{
int f = 0;
for(int i = 2;i < 60;++i)
{
int flag = 1;

for(int j = 2;j < i;++j)
if(i % j == 0)
{
flag = 0;
break;
}
if(flag) prim[f++] = i;
}
return f;
}

int calc(INT a,INT b,INT n)
{
INT s = 1;
while(b--)
{
if((INT)(n / a) <= s) return 0;
s *= a;
}
return 1;
}
int main()
{
INT n;
int num = dabiao();
while(scanf("%I64d",&n)!=EOF)
{
INT tot = 1;
for(int i = 0;i < num;++i)
{
INT temp = (INT)pow((double)n,1.0 / prim[i]);
if(temp == 1 ) break;   //开方之后不足1的话,则退出
tot += temp - 1;   //减1是因为每次都会统计到1
}
for(int i = 0;i < num;++i)
for(int j = i+1;j < num;++j)
{
INT temp = pow((double)n,1.0/(prim[i] * prim[j]));
if(temp == 1) break;
tot -= temp - 1;
}
for(int i = 0;i < num;++i)
for(int j = i + 1;j < num;++j)
for(int k = j + 1;k < num;++k)
{
INT temp = pow((double)n,1.0/(prim[i] * prim[j] * prim[k]));
if(temp == 1) break;
tot += temp - 1;
}
printf("%I64d\n",tot);
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: