jzoj6268. [지방 선거 시뮬레이션 8.10] 저렴한

제목 설명

기술
여기에 사진 설명 삽입


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);
}

추천

출처blog.csdn.net/gmh77/article/details/99718471