您的位置:首页 > 其它

hdu 3208 Integer’s Power(容斥原理)

2017-08-18 19:59 162 查看
看着和hdu 2204有些相似,但是解法还是有差距的。求(a,b)之间的数字的幂的和,求出来1-b的减去1-(a-1)的即可。一个数字表示成M^K,取那个最大的K作为这个数字的幂。考虑枚举所有的幂,2^60>1e18,所以从2枚举到59就行。比如64可以表示成2^6,4^3,8^2,则64的幂就是6。但是有重复,就用到容斥了,8^2已经包含64了,但是64的幂是6,所以就要去掉8^2这种情况,也要去掉4^3的情况。还会发现6%3=0,6%2=0。

参考:http://blog.csdn.net/u010660276/article/details/45460973

学会了写开高次方的函数,涨知识了。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

const LL INF = 1e18+300;
const int MAXN = 110;
const LL T = (1LL<<31);

LL pow_mul(LL x,LL k)
{
LL ans=1;
while(k)
{
if(k&1)
{
double judge=1.0*INF/ans;
if(x>judge)return -1;
ans*=x;
}
k>>=1;
if(x>T&&k>0)return -1;
x*=x;
}
return ans;
}

LL find(LL x,LL k)
{
LL r=(LL)pow(x,1.0/k);
LL p=pow_mul(r,k);
if(p==x)return r;
if(p>x||p==-1)r--;
else
{
LL tmp=pow_mul(r+1,k);
if(tmp!=-1&&tmp<=x)r++;
}
return r;
}

LL num[MAXN];

LL solve(LL n)
{
memset(num,0,sizeof(num));
int numLen = 0,i;
num[1] = n;
for(i = 2; i < 60; ++i)
{
num[i] = find(n,i)-1;
if(num[i] == 0)
break;
}
numLen = i;
for(int j = numLen-1; j > 0; --j)
for(int k = 1; k < j; ++k)
if(j%k == 0)
num[k] -= num[j];
LL res = 0;
for(int i = 1; i < numLen; ++i)
res += num[i]*i;
return res;
}

int main()
{
LL a,b;
while(cin >> a >> b && a+b)
cout << solve(b)-solve(a-1) <<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: