您的位置:首页 > 其它

HDU4542-小明系列故事——未知剩余系(数论)

2013-04-12 15:16 225 查看
题目在http://acm.hdu.edu.cn/showproblem.php?pid=4542

当type=0的时候,就是求因子个数为k的最小数。我们知道,一个数可以这样分解:



其中p1,p2……,pr都是素数并且都不相同

所以思路就是将k这个数进行分解,然后搜索出所有的情况,找到最小值即可。

当type=1的时候,设我们求的数为n,那么这个数的因子个数就为n-k;求这样一个最小的n。

我们定义一个数组ip[],ip[i]=j,表示i这个数的因子个数为i-j。我们利用筛选素数的思想,筛选出

因子个数为i-j,并且这个数为i的最小数。这个ip是一个滚动数组,把它当成两个数组即可。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;

typedef __int64 LL;

const int ns=50000,top=15;
const LL INF=((LL)1<<62)+1;

LL ans;
int m,k,type,cnt;
int ip[ns+10];
int p[100]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47};

void prim()
{
for (int i=1;i<=ns;i++)
{
ip[i]+=i;
for (int j=i;j<=ns;j+=i)
{
ip[j]--;
}
if (!ip[ip[i]])
ip[ip[i]]=i;
ip[i]=0;
}
}

void dfs(int fm,LL t,int pos)
{
if (fm==k&&ans>t) ans=t;
if (fm>=k||(pos>=top)) return ;
for (int i=1; i<=62; i++)
{
if (t>ans/p[pos]||fm*(i+1)>k) return;
t*=p[pos];
if (k%(fm*(i+1))==0)
dfs(fm*(i+1),t,pos+1);
}
}

int main()
{
prim();
int T,cas=0;
scanf("%d",&T);
while (T--)
{
scanf("%d%d",&type,&k);
if (type)
{
ans=ip[k];
}
else
{
ans=INF;
dfs(1,1,0);
}
printf("Case %d: ",++cas);
if (ans==0) printf("Illegal\n");
else if (ans>=INF) printf("INF\n");
else printf("%I64d\n",ans);
}
return 0;
}








内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: