hdu 4542 小明系列故事——未知剩余系 夜

http://acm.hdu.edu.cn/showproblem.php?pid=4542

这个题 type 为 0 和 type 为 1 的求解方法居然没有什么关系,无语

对于 type 为1 的情况:

可以发现随着x的增大[1~x]中不是x的约数的数也基本上是增大的

所以可以开一个比较大的数组,用求解素数的思路求出每个数中它的非约数的个数

然后找到某个数量第一次出现的x 如果没有出现,就可以简单的认为是没有这种情况

对于type为0的情况:

必须先知道一点

假设P(i)代表某个素数a(i)代表这个素数的幂

那么任何一个数都可以分解成  ( P(1)^a(1) )*( P(2)^a(2) )*( P(3)^a(3) )*.............*( P(k)^a(k) )

而且这个数的约数的数量为  (a(1)+1)*(a(2)+1)*(a(3)+1)*.............*(a(k)+1)

在这种情况下开一个二维数组进行DP就可以了

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<queue>
#include<algorithm>
#include<cmath>

#define LL long long
#define ULL unsigned long long
using namespace std;
const int INF=0x3f3f3f3f;
const LL LINF=ceil(pow(2.0,62));
const double DINF=(pow(2.0,62));
const int N=100005;
const int M=17;
const int K=50000;
int a[N],b[N];
int p[]={1,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
LL dp[M][K];
int main()
{
    //freopen("data.in","r",stdin);
    memset(dp,-1,sizeof(dp));
    LL tmp=1;
    for(int j=0;j<63;++j)
    {
        dp[1][j+1]=tmp;
        if(double(tmp)*double(p[1])>DINF)
        break;
        tmp=tmp*p[1];
    }
    for(int i=1;i<M-1;++i)
    for(int j=1;j<K;++j)
    if(dp[i][j]!=-1)
    {
        tmp=p[i+1];
        for(int l=1;l<63;++l)
        {
            if(double(dp[i][j])*double(tmp)>DINF) break;
            int r=j*(l+1);
            if(r>=K) break;
            if(dp[i+1][r]==-1||dp[i+1][r]>dp[i][j]*tmp)
            dp[i+1][r]=dp[i][j]*tmp;
            if(double(tmp)*double(p[i+1])>DINF) break;
            tmp=tmp*p[i+1];
        }
    }
    for(int i=1;i<N;++i)
    a[i]=i;
    memset(b,-1,sizeof(b));
    for(int i=1;i<N;++i)
    for(int j=i;j<N;j=j+i)
    {
        --a[j];
        if(b[a[i]]==-1)
        b[a[i]]=i;
    }
    int T;
    scanf("%d",&T);
    for(int w=1;w<=T;++w)
    {
        int k,n;
        scanf("%d %d",&k,&n);
        printf("Case %d: ",w);
        if(k==1)
        {
            if(b[n]==-1)
            printf("Illegal\n");
            else
            printf("%d\n",b[n]);
        }else
        {
            LL ans=-1;
            for(int i=1;i<M;++i)
            if(dp[i][n]!=-1)
            {
                if(ans==-1||dp[i][n]<ans)
                ans=dp[i][n];
            }
            if(ans==-1||ans>LINF)
            printf("INF\n");
            else
            cout<<ans<<endl;
        }
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/liulangye/p/2994837.html