Link
不难发现,返回值错误当且仅当在\(n\)的前面,存在连续的\(k\)个数,使得这\(k\)个数均小于这\(k\)个数前面的最大值。
\(f_i\)表示长度为\(i\)的未由if(offset==k)return ans;返回的排列个数。
枚举\(i\)所在的位置\(j\),转移为\(f_i=\sum\limits_{j=i-k+1}^if_{j-1}{i-1\choose i-j}(i-j)!=(i-1)!\sum\limits_{j=i-k}^{i-1}\frac{f_j}{j!}\)
\(g_i=\frac{f_i}{i!}\),那么\(g_i=\frac{\sum\limits_{j=i-k}^{i-1}g_j}i\),前缀和优化即可。
最后\(ans=n!-\sum\limits_{i=1}^nf_{i-1}{n-1\choose n-i}(n-i)!=(n-1)!(n-\sum\limits_{i=1}^ng_{i-1})\)

#include<cstdio>
const int N=1000007,P=1000000007;
int inv[N],f[N];
int main()
{
    int n,m,fac=1;scanf("%d%d",&n,&m),inv[0]=inv[1]=1;
    if(n<=m) m=n-1;
    for(int i=2;i<n;++i) inv[i]=1ll*(P-P/i)*inv[P%i]%P,fac=1ll*i*fac%P;
    for(int i=0;i<=m;++i) f[i]=i+1;
    for(int i=m+1;i<n;++i) f[i]=(1ll*(f[i-1]-f[i-m-1]+P)*inv[i]+f[i-1])%P;
    printf("%lld",1ll*fac*(n-f[n-1]+P)%P);
}