这个题我一开始以为只是个简单的DP,接着竟然交了个超时,我也很绝望,后来发现不能用DP的思路去做,因为不能出现重复出现的数字。
然后就觉得是找规律的题目。辉哥找出来的规律,然后我说了一下自己的想法就上课去了。今天补上这个题。
code:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
const int maxn = 1e5;
const LL mod = 1e9+7;
LL add[maxn], mul[maxn];
LL quickmi(LL a,LL b)
{
LL res=1;
while(b!=0)
{
if(b%2==1)
{
res*=a;
res=res%mod;
}
b=b/2;
a=a*a%mod;
}
return res;
}
LL inv(LL a, LL n)
{
return quickmi(a,n-2);
}
void init()
{
memset(add, 0, sizeof(add));
memset(mul, 0, sizeof(mul));
add[0] = add[1] = 1;
add[2] = 2;
mul[0] = mul[1] = 1;
mul[2] = 2;
for(LL i = 3; i < maxn; i++){
add[i] = add[i-1]+i;
mul[i] = (mul[i-1]*i)%mod;
}
}
int main()
{
init();
LL T, x;
scanf("%I64d", &T);
while(T--)
{
scanf("%I64d", &x);
if(x <= 4)
{
printf("%lld\n", x);
continue;
}
int l=2,r=maxn-5;
while(l < r)
{
int mid = (l+r+1)/2;
if(add[mid] <= x) l = mid;
else r = mid-1;
}
LL temp = x - add[l];
if(temp == l)
printf("%lld\n", mul[l]*inv(2, mod)%mod*(l+2)%mod);
else if(temp == 0)
printf("%I64d\n", mul[l]);
else
printf("%lld\n", mul[l-temp]*mul[l+1]%mod*inv(mul[l-temp+1], mod)%mod);
}
return 0;
}