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