设为首页 加入收藏

TOP

HDU3208(区间指数和)
2014-11-23 21:46:36 来源: 作者: 【 】 浏览:5
Tags:HDU3208 区间 指数
题意:给两个数a和b,然后在闭区间[a,b]内的每一个数y都可以表示成x^k=y,要求x尽量最小,k尽量最大,然后求所有的k之和。
分析:对于这个题,我们首先要知道是基于以下的事实来计算的:
对于一个数n,从1~n中假设有x个数是满足p^k形式的,这里的k最多到62,那么对于每一个k,我们需要找到这个数x满足x^k最
接近n,那么现在的问题就是对于每一个k找出对应的x,那么这个怎么找呢?
我们可以这样考虑,由于是找最接近的,我们可以先大致确定一个数r,那么可以通过r=pow(n,1/k)来计算,然后我们分别计
算(r-1)^k,r^k,(r+1)^k,然后看这三个数哪个最接近n就行了,这里要注意(r+1)^k计算时可能会超过LL,所以有一些处理。
然后就是相当于容斥的部分了。
#include   
#include   
#include   
#include   
  
using namespace std;  
typedef long long LL;  
  
const LL INF=1e18+300;  
const LL T=(LL)1<<31;  
  
LL num[105];  
  
LL multi(LL a,LL b)  
{  
    LL ans=1;  
    while(b)  
    {  
        if(b&1)  
        {  
            double judge=1.0*INF/ans;  
            if(a>judge) return -1;  
            ans*=a;  
        }  
        b>>=1;  
        if(a>T&&b>0) return -1;  
        a=a*a;  
    }  
    return ans;  
}  
  
LL find(LL x,LL k)  
{  
    LL r=(LL)pow(x,1.0/k);  
    LL t,p;  
    p=multi(r,k);  
    if(p==x) return r;  
    if(p>x||p==-1) r--;  
    else  
    {  
        t=multi(r+1,k);  
        if(t!=-1&&t<=x) r++;  
    }  
    return r;  
}  
  
LL Solve(LL n)  
{  
    int i,k=0;  
    memset(num,0,sizeof(num));  
    if(n<=3) return n;  
    num[1]=n;  
    for(i=2;i<63;i++)  
    {  
        num[i]=find(n,i)-1;  
        if(!num[i]) break;  
    }  
    k=i;  
    for(int i=k-1;i>0;i--)  
        for(int j=1;j>m>>n)  
    {  
        if(m==0&&n==0) break;  
        cout< 
  


】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇uva 674 Coin Change(完全背包) 下一篇区间dp-zoj3541-The Last Puzzle

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·一篇说人话的文章, (2025-12-27 07:50:09)
·Python Web框架哪家 (2025-12-27 07:50:06)
·基于Python的数据分 (2025-12-27 07:50:03)
·深入理解 Java 集合 (2025-12-27 07:22:48)
·Java集合框架全面解 (2025-12-27 07:22:45)