Topic link: http://exercise.acmcoder.com/online/online_judge_ques?ques_id=3370&konwledgeId=40
Problem-solving ideas: We can first arrange m people, the number of solutions is m!, and then consider inserting a space between two people, assuming that x0 spaces are inserted in front of the first person, between the first person and the second person Insert x1 spaces. . .
Then we have: x0+x1+x2+....+xm=nm (after removing m people, only nm positions are left). To meet the requirements of the title, no two people are adjacent, then, xi>=1 i=1,2,3,...,m-1.
Since the first person and the last person can be adjacent to each other, they need to be considered separately:
- x0==0, then you need xm>=1
- xm==0, then you need x0>=1
- x0>=1 && xm>=1
Consider the third case first, that is, x0+x1+x2+...+xm=nm, which can be calculated by the partition method. For example, x1+x2+x3=5, you can write 5 as 5=1+1+1+1+1, now you need to choose two of the four "+" signs, so that the last three numbers are added, so it is C(4-1, 3-1). For our problem we have ans=C(nm-1, m) (because there are m+1 numbers)
For the first and second cases, it is equivalent to x1+x2+...+m=nm, the solution is the same as above, ans=C(nm-1, m-1)
Finally add all the results together. The final result is: m!(C(nm-1,m) + 2*C(nm-1, m-1))
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 typedef long long LL; 5 const int MAXN = 100005; 6 const LL MOD7 = 1e9+7; 7 8 LL n,m; 9 LL pow(LL a, LL b, LL MOD) 10 { 11 LL ans = a%MOD; 12 LL res=1LL; 13 while (b) 14 { 15 if (b&1) res=res*ans%MOD; 16 ans=ans*ans%MOD; 17 b>>=1; 18 } 19 return res; 20 } 21 22 LL inverse(LL a, LL p) 23 { 24 return pow(a,p,p-2); 25 } 26 27 void solve(LL n, LL m) 28 { 29 LL ans=1LL; 30 for (int i=1;i<=m-1;++i) ans=ans*(n-m-1-i+1)%MOD7; 31 LL res=0LL; 32 res=(ans*m*2%MOD7+ans*(n-m*2)%MOD7)%MOD7; 33 printf("%lld\n",res); 34 } 35 36 int main() 37 { 38 #ifndef ONLINE_JUDGE 39 freopen("test.txt","r",stdin); 40 #endif // ONLINE_JUDGE 41 int Case; 42 scanf("%d",&Case); 43 while (Case--) 44 { 45 scanf("%lld%lld",&n,&m); 46 if (n<2*m) printf("0\n"); 47 else if (m==1LL) printf("%lld\n",n); 48 else solve(n,m); 49 } 50 return 0; 51 }