제목 설명
기술
n, k 행에 두 개의 정수 입력
1e9 + 모듈로 답을 나타내는 한 줄에 정수 ans를 출력 합니다.
샘플 입력
샘플 입력 1
5 2
샘플 입력
2100 50
샘플 출력
샘플 출력 1
12
샘플 출력 2
400502129
데이터 제약
대답
f [i]는 적어도 i 번 검은 색으로 염색 할 수있는 계획 의 수를 나타내면
답은 ans = ∑ i ⩾ 0 f [i] − (n − k + 1)! Ans = \ sum_ {i \ geqslant 0} {f [i]}-(n-k + 1)!N 개의 S=∑난 ⩾ 0f [ i ]−( n−케이+1 ) !
각 순열이 계산 되었기 때문에 (로우 핸드 횟수 + 1), 순열 수는 끝에서 빼야합니다
k = 1 또는 k = n
답은 0
k * 2≥n
머리와 꼬리를 넣은 후 검은 색으로 염색 할 수 있으니 중간에 넣어주세요
k = 2
열거 i, 조합의 수는 마음대로 계산할 수 있습니다.
시간 : O (n)
k≥1000
f [i]는 직접 계산하기 쉽지 않음
공차 및 제외 i 각각 에 대해 간격이 ≥ m 인 j 개 이상의 솔루션을 찾고
간격이 <k 인 솔루션 만 남도록 계산 하십시오.
증명 :
k 인 경우 간격 ≥ k
계산 된 횟수 = ∑ i = 0 k (− 1) i C ki \ sum_ {i = 0} ^ {k} {(-1) ^ {i} C_ {k} ^ {i}}∑나는 = 0케이( − 1 )나는 C케이나는
Yanghui 삼각형 에서 첫 번째 행의 홀수 및 짝수 합계 = 1이고 나머지는 0입니다 (현재 행의 홀수 / 짝수 합계 = 이전 행의 홀수 + 짝수, 초기 홀수 = 1 옴 = 0)
시간 : O (n 2 / k), 30 % 미만이므로 특별한 처리가 필요합니다.
암호
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
#define mod 1000000007
#define Mod 1000000005
using namespace std;
long long jc[1000001];
long long Jc[1000001];
long long w[1000001];
long long f[1000001];
int n,m,i,j,k,l;
long long ans;
long long qpower(long long a,int b)
{
long long ans=1;
while (b)
{
if (b&1)
ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
long long C(int n,int m)
{
return jc[n]*Jc[m]%mod*Jc[n-m]%mod;
}
int main()
{
freopen("jian.in","r",stdin);
freopen("jian.out","w",stdout);
scanf("%d%d",&n,&m);
if (n==m)
{
printf("0\n");
return 0;
}
jc[0]=1;jc[1]=1;
Jc[0]=1;Jc[1]=1;
w[1]=1;
fo(i,2,n)
{
w[i]=(long long)mod-(mod/i)*w[mod%i]%mod;
jc[i]=jc[i-1]*i%mod;
Jc[i]=Jc[i-1]*w[i]%mod;
}
if (m==1)
{
printf("0\n");
return 0;
}
if (m+m>=n)
{
f[0]=jc[2]*jc[(n-m+1)-2]%mod;
fo(i,1,(n-m+1)-2)
f[i]=C((n-m+1)-2,i)*jc[i+2]%mod*jc[(n-m+1)-2-i]%mod;
}
else
if (m==2)
{
fo(i,(n-m-m-1)/m+1,n-m-1)
f[i]=C(i+1,n-m-1-i)*jc[i+2]%mod*jc[(n-m+1)-(i+2)]%mod;
}
else
{
fo(i,(n-m-m-1)/m+1,n-m-1)
{
fd(j,min(i+1,(n-m-1-i)/m),0)
if (!(j&1))
f[i]=(f[i]+C(i+1,j)*C(n-m-1-i-j*m+(i+1)-1,(i+1)-1)%mod)%mod;
else
f[i]=(f[i]-C(i+1,j)*C(n-m-1-i-j*m+(i+1)-1,(i+1)-1))%mod;
f[i]=f[i]*jc[i+2]%mod*jc[(n-m+1)-(i+2)]%mod;
}
}
ans=f[0];
fd(i,n-m-1,1)
ans=(ans+f[i])%mod;
ans-=jc[n-m+1];
printf("%lld\n",(ans%mod+mod)%mod);
}