https://www.lydsy.com/JudgeOnline/problem.php?id=4517
https://www.luogu.org/problemnew/show/P4071
求有多少种长度为 n 的序列 A,满足以下条件:1 ~ n 这 n 个数在序列中各出现了一次若第 i 个数 A[i] 的值为 i,则称 i 是稳定的。序列恰好有 m 个数是稳定的满足条件的序列可能很多,序列数对 10^9+7 取模。
sb题,有C(n,m)种可能稳定,剩下的就是使n-m错排即可。
错排公式d[i]=(i-1)*(d[i-1]+d[i-2])
(虽然这个公式是我现查的……)
#include<cmath> #include<queue> #include<vector> #include<cstdio> #include<cctype> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int p=1e9+7; const int N=1e6+5; inline int read(){ int X=0,w=0;char ch=0; while(!isdigit(ch)){w|=ch=='-';ch=getchar();} while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } int qpow(int k,int n){ int res=1; while(n){ if(n&1)res=(ll)res*k%p; k=(ll)k*k%p;n>>=1; } return res; } int jc[N],inv[N],d[N]; inline int C(int n,int m){ return (ll)jc[n]*inv[m]%p*inv[n-m]%p; } void init(int n){ jc[0]=1; for(int i=1;i<=n;i++)jc[i]=(ll)jc[i-1]*i%p; inv[n]=qpow(jc[n],p-2); for(int i=n-1;i;i--)inv[i]=(ll)inv[i+1]*(i+1)%p; inv[0]=1; d[0]=1;d[1]=0;d[2]=1; for(int i=3;i<=n;i++)d[i]=(ll)(i-1)*(d[i-1]+d[i-2])%p; } int main(){ init(N-5); int T=read(); while(T--){ int n=read(),m=read(); printf("%lld ",(ll)C(n,m)*d[n-m]%p); } return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++