hdu 3208 Integer’s Power (坑精度,容斥)

题意:

给出一个范围,求这个范围每个数power的和,power的定理例如:64=2^6,99=99^1,16=2^4,要尽量让指数最大,那么对应的指数就是power。

题解:

枚举指数,计算,然后去重。精度fuck!

#include<iostream>
#include<math.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define B(x) (1<<(x))
void cmax(int& a,int b){ if(b>a)a=b; }
void cmin(int& a,int b){ if(b<a)a=b; }
typedef __int64 ll;
const int oo=0x3f3f3f3f;
const ll OO=1LL<<61;
const int MOD=1000007;
const int maxn=70;
const ll INF=(ll)1e18+300;
ll cnt[maxn];

ll quick_pow(ll a,int k){
    ll ans=1;
    while(k){
        if(k&1){
            double t=1.0*(INF)/ans;
            if(t<a)return -1;
            ans*=a;
        }
        k>>=1;
        if(a>(1LL<<31)&&k>0)return -1;
        a*=a;
    }
    return ans;
}

ll get_cnt(ll n,int k){
    ll ans=(ll)pow(n,1.0/k);
    ll temp=quick_pow(ans,k);
    if(temp==n) return ans;
    if(temp>n||temp==-1) ans--;
    else{
        temp=quick_pow(ans+1,k);
        if(temp<=n&&temp!=-1) ans++;
    }

    return ans;
}

ll solve(ll n){
    if(n<=3)return n;
    int END=62;
    cnt[1]=n;
    for(int i=2;i<63;i++){
        cnt[i]=get_cnt(n,i)-1;
        if(cnt[i]<=0){
            END=i-1;
            break;
        }
    }
    for(int i=END;i>=1;i--){
        for(int j=1;j<i;j++){
            if(i%j==0) cnt[j]-=cnt[i];
        }
    }
    ll ans=0;
    for(int i=1;i<=END;i++) ans+=i*cnt[i];
    return ans;
}

int main(){
    //freopen("E:\\read.txt","r",stdin);
    ll a,b;
    while(scanf("%I64d %I64d",&a,&b)!=EOF){
        if(a==0&&b==0)break;
        ll ans=solve(b)-solve(a-1);
        printf("%I64d\n",ans);
    }
    return 0;
}




你可能感兴趣的:(hdu 3208 Integer’s Power (坑精度,容斥))