1. 程式人生 > >HDU-5976 Detachment

HDU-5976 Detachment

貪心+逆元

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=100000+10;
const ll mod=1e9+7;
ll p[N];
ll mypow(ll a,ll b)
{
    ll ret=1;
    while(b)
    {
        if(b&1) ret*=a,ret%=mod;
        a*=a;
        a%=mod;
        b>>=1;
    }
    return ret;
}
void init()
{
    p[1]=1;
    for(int i=2;i<N;i++)
        p[i]=p[i-1]*i%mod;
}
int main()
{
    init();
    int T;
    scanf("%d",&T);
    ll x;
    while(T--)
    {
        scanf("%lld",&x);
        if(x<=4)
        {
            printf("%lld\n",x);
            continue;
        }
        ll n=sqrt(2*x)+1;
        while((n-1)*(n+2)>2*x) n--;
        ll num=x-(n-1)*(n+2)/2;
        ll b=num/(n-1);
        ll t=n+b+1-num%(n-1);
        ll ans=p[n+b];
        if(num%(n-1)) ans=p[n+b+1];
        for(int i=0;i<b;i++)
        {
            ans*=mypow(2+i,mod-2);
            ans%=mod;
        }
        if(num%(n-1))
        ans*=mypow(t,mod-2);
        ans%=mod;
        printf("%lld\n",ans);
    }
    return 0;
}