您的位置:首页 > 其它

hdu 5976 Detachment

2017-09-30 11:13 190 查看
http://acm.hdu.edu.cn/showproblem.php?pid=5976

拆数字,并求所拆的数字乘积的最大值,显然是拆成2*3*4*5*。。。*n这样的形式,但会存在

多出来的数字,如果多出来的数字加上2能够等于n+1,则答案就是2*3*。。。*n/2*(n+1),

如果小于n+1,则可以将多出来的数加到前面的3或者4或者5或者后面的数上,是的所加的那个数加上多出来的数字后正好等于n+1,则答案就是2*3*4*5*....*n/(i)*n+1,可以预处理打表前缀和和前缀积,并且除法取模需要用到乘法逆元。

#include<iostream>
#include<cstdio>
using namespace std;
long long int MOD=7+1e9;
int
4000
qzh[55555];
long long int qzj[55555];
int ny[55555];
void ycl()
{
qzj[1]=1;
qzh[1]=0;
ny[1]=1;
for(int i=2;i<=48888;i++)
{
ny[i]=(MOD-MOD/i)*ny[MOD%i]%MOD;
qzj[i]=(i*qzj[i-1])%MOD;
qzh[i]=i+qzh[i-1];
}
}
int main()
{

int t;long long int ans;	int a;
int lef,rig,mid;
while(scanf("%d",&t)!=EOF)
{
ycl();
while(t--)
{

scanf("%d",&a);
if(a<5)printf("%d\n",a);
else {
lef=2;
rig=48888;
mid=(lef+rig)>>1;
while(lef+1<rig)
{
if(qzh[mid]>a)
{
rig=mid;
mid=(lef+rig)>>1;
}
else{
lef=mid;
mid=(lef+rig)>>1;
}
}
int dy=a-qzh[lef];
if(2+dy>=lef+1)ans=qzj[lef]*ny[2]%MOD*(2+dy)%MOD;
else ans=qzj[lef]*ny[lef+1-dy]%MOD*(lef+1)%MOD;
ans=(ans+MOD)%MOD;
printf("%lld\n",ans);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: