【水题】HDU 5646

来源:互联网 发布:长期成本 知乎 编辑:程序博客网 时间:2024/05/17 07:32

想要乘积大,那么挑的数肯定要越相近越好。想过分治,但是不能保证挑的数不重复。

并且要满足sum(1,m) >= n。所以基于1,2,3,..m的数列。。于是对于1-m每个数都加上(n-sum(m))/m,再从后往前把多余的数值补上去。。

其实这是打表发现的。。= =

#include <cstdio>#include <cstring>#include <iostream>using namespace std;#define ll long longll mod = 1000000007;ll check(ll x){    ll a = x/2;    if(!(x%2)) return (1+x)*a;    else return ((1+x)*a%mod+a+1);}int main(){    ll t,n,m;        cin>>t;    while(t--)    {        scanf("%lld%lld",&n,&m);        ll sum=1;        ll test = check(m);        if(test>n) {cout<<"-1"<<endl;continue;}        if(test==n)        {            for(ll i=1;i<=m;i++)            {                sum=(sum*i)%mod;            }            printf("%lld\n",sum);            continue;        }        ll a=(n-test)/m,b=(n-test)%m;        for(ll i=a+m,j=0;j<m;j++,i--)        {            if(b>0)            {                sum=(sum*(i+1));                                b--;            }            else            {                sum=(sum*i);            }            sum%=mod;                    }        printf("%lld\n",sum);    }    return 0;}


0 0