uva 11752 The Super Powers 素数+大数判断大小

题目链接:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2852

题意:找到在[1,2^64-1]区间范围内的所有Super Powers数,Super Powers数指的是可以写成另外两个正数的次幂;

   例如:1=1^1,1=1^20;   64=8^2,64=4^4;

思路:1另外算,从2开始,他的指数如果不是素数,由于算数基本定理,即可将指数分解成另外多个素数的乘积,即是Super Powers数;

   利用log判断是否超过2^64-1,记得用无符号long long ;

#include<bits/stdc++.h>
using namespace std;
#define ll unsigned long long
#define esp 1e-13
const int N=1e3+10,M=1e6+1000,inf=1e9+10,mod=1000000007;
const int MAXN=66000;
ll prime[MAXN];
bool vis[MAXN];
map<ll,ll>flag;
struct cmp1{
    bool operator ()(ll &a,ll &b){
        return a>b;
    }
};
priority_queue<ll, vector<ll> ,cmp1>q;
ll Prime(ll n)
{
    ll cnt=0;
    memset(vis,0,sizeof(vis));
    for(ll i=2;i<n;i++)
    {
        if(!vis[i])
        prime[cnt++]=i;
        for(int j=0;j<cnt&&i*prime[j]<n;j++)
        {
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)
            break;
        }
    }
    return cnt;
}
ll quickpow(ll a,ll b)
{
    ll sum=1;
    while(b)
    {
        if(b&1)sum*=a;
        a*=a;
        b>>=1;
    }
    return sum;
}
int main()
{
    ll cnt=Prime(MAXN);
    ll x,y,z,i,t;
    ll ans=0;
    for(i=0;i<64;i++)
    ans+=quickpow(2ll,i);
    printf("1
");
    for(i=2;i<MAXN;i++)
    {
        ll sum=i,t=1;
        double hh=(double)(log(sum*1.0)/log(10))+(double)(log(i*1.0)/log(10))-(double)(log(ans*1.0)/log(10));
        while(hh<=-esp)
        {
            sum*=i;
            t++;
            if(!flag[sum]&&vis[t])
            {
                q.push(sum);
                flag[sum]=1;
            }
            hh=(double)(log(sum*1.0)/log(10))+(double)(log(i*1.0)/log(10))-(double)(log(ans*1.0)/log(10));
        }
    }
    while(!q.empty())
    {
        printf("%llu
",q.top());
        q.pop();
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/jhz033/p/5752416.html