1 4Sample Output
4
给出一个正整数,给这个数分解n段,但是各段不能有相同的数,求这些分法中各段乘积最大的答案;
这道题最开始想到分段,第一段是2,第二段是3,第三段是4,以此类推,这样是乘积最大的分段方法,
如果最后还剩一个数,就把这个分成n个1,分别加到每个头上,例如12,分成2,3,4后剩3,就变成3,4,5;
由于测试组数过多,分段要利用等差数列前n项求和公式求出分到第几项,不能每次算得时候都重新乘,取余,所以 要先用数组打表记录从2乘到N的乘积,然后中间空哪个数就在求这个数的逆元,在取余就好了;例如12,分成3,4,5;利用打表求得是2乘到5,由于多乘了2,所以求出2的逆元,再重新乘取余就好了;注意求得逆元是负数,要变成正数。
#include ans=(su[k+1]*p)%mod; ans=(su[k]*p)%mod;
#include
#include
using namespace std;
typedef long long ll;
#define mod 1000000007
ll f[50000];
void Ex_gcd(ll a, ll b, ll &x, ll &y)
{
if(b == 0)//递归出口
{
x = 1;
y = 0;
return;
}
ll x1, y1;
Ex_gcd(b, a%b, x1, y1);
x = y1;
y = x1-(a/b)*y1;
}
ll su[50000];
void dabiao()
{
su[1]=1;
su[2]=2;
for(int i=3;i<=45000;i++)
{
su[i]=(su[i-1]*i)%mod;
}
}
int main()
{
int T;
ll a;
scanf("%d",&T);
dabiao();
while(T--)
{
ll ans=1;
scanf("%lld",&a);
if(a<=4)
printf("%lld\n",a);
else
{
f[0]=1;
ll k=(ll)((-1+sqrt(9+8*a))/2);
// cout<
//cout<
{
ll p=0,q;
Ex_gcd(k-tmp+1,mod,p,q);
if(p<0) p=(p%mod+mod)%mod;
// cout<
//cout<
else
{
ll p,q;
Ex_gcd(2,mod,p,q);
if(p<0) p=(p%mod+mod)%mod;
//cout<
ans=(ans*(k+2))%mod;
}
printf("%lld\n",ans);
}
}
return 0;
}