Detachment(数论)

在这里插入图片描述

思路:

先按照正常构造自然数:
S = 2 × 3 × … × ( n − Δ x ) × ( n − Δ x + 1 ) × … × n S=2\times 3\times \ldots \times \left( n-\Delta x\right) \times \left( n-\Delta x+1\right) \times \ldots \times n S=2×3××(nΔx)×(nΔx+1)××n
一般会多出一个数 Δ x \Delta x Δx ( Δ x ≤ n \Delta x\leq n Δxn)
S = 2 × 3 × … × ( n − Δ x ) × ( n − Δ x + 2 ) × … × ( n + 1 ) ( Δ x < n − 1 ) \begin{aligned}S=2\times 3\times \ldots \times \left( n-\Delta x\right) \times \left( n-\Delta x+2\right) \times \ldots \times \left( n+1\right) \\ \left( \Delta x <n-1\right) \end{aligned} S=2×3××(nΔx)×(nΔx+2)××(n+1)(Δx<n1)
S = 3 × 4 × … × ( n + 1 ) ( Δ x = n − 1 ) \begin{aligned}S=3\times 4\times \ldots \times \left( n+1\right) \\ \left( \Delta x=n-1\right) \end{aligned} S=3×4××(n+1)(Δx=n1)
S = 3 × 4 × … × ( n + 2 ) ( Δ x = n ) \begin{aligned}S=3\times 4\times \ldots \times \left( n+2\right) \\ \left( \Delta x=n\right) \end{aligned} S=3×4××(n+2)(Δx=n)
首先通过前缀和,前缀积,线性逆元进行数据预处理 , 之后通过二分优化找到 Δ x \Delta x Δx,最后带入公式分类讨论即可

代码:

#include<iostream>
#define LL long long
#define fo(i,a,b) for(int i=a;i<b;i++)
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
using namespace std;
const LL mod=1e9+7;
const int N=1e5+5;
LL sum[N],mul[N],inv[N];
void init(){
    sum[1]=0;mul[1]=1;inv[1]=1;//1的逆元是1
    fo(i,2,N){
        sum[i]=sum[i-1]+i;
        mul[i]=(mul[i-1]%mod)*i%mod;
        inv[i]=(mod-mod/i)*inv[mod%i]%mod;
    } 
}
LL t,x,l,r,mid;
LL ans=0;
int main(){
    init();
    scanf("%d",&t);
    while(t--){
        scanf("%lld",&x);
        if(x<5){
            printf("%lld\n",x);
            continue;
        }
        l=2;r=N;
        while(l<r){
            mid=(l+r+1)>>1;
            if(sum[mid]<=x)l=mid;
            else r=mid-1;
        }
        LL res=x-sum[l];
        if(res==(l-1) || res==l)ans=(mul[l]*inv[2])%mod*(res+2)%mod;
        else ans=mul[l]*inv[l-res+1]%mod*(l+1)%mod;
        printf("%lld\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值