@atcoder - 일본어 학생 선수권 대회 2019 자격 - F @ 사탕 징벌


@기술@

찾아 다음과 같은 조건의 길이는 N 음이 아닌 정수 순서 A1, A2, ..., 수의를 충족.
(1) L≤A1 + A2 + ... + AN≤R.
N 개의 요소가 비 증가 순서로 배열 된 후 (2), 제 M 원소 M + 1 개 요소와 동일하다.
10 ^ 9 + 7 모드에 답변 해주세요.

제약 조건은
모든 숫자는 정수입니다.
1≤M <N≤3 10 ^ 5 × 1≤L≤R≤3 × 10 ^ 5.

입력
양식을 다음 입력 :
NMLR

출력
출력 시퀀스 번호 9 ^ 7 + 10 MOD.

샘플 입력 1
4 2 3 7
샘플 출력 1
105

샘플 입력 2
2 1 4 8
샘플 출력 2
(3)

@해결책@

심지어 마지막 질문에 있지만, 사실이 질문은 상대적으로 물을 수를 결합 (그래서 왜 나는 아 피드를 할 여유가 없다).

그래서 F는 (N은 M, S)는 0 <= A1 + A2 + ... + <= S를 만족시키는 시퀀스를 나타내며,시 피사체 만족 두 번째 조건의 최종 답변 = F (N, M, 상기 답 , R) - F (N, M, L - 1).

첫째 단 A1 + A2 + ... + 고려 <= S 조건이되도록 B의 = S를 - A1 - A2 - ... - AN, 다음 B> = 0, A1 + A2 + ... + B + = S. 변환 방정식 부등식에 넣을 수 후, 세퍼레이터 신속 통계 프로그램 번호를 처리 할 수 ​​있도록 (실제로 많은 표준 회전 완화 형 선형 계획법 등).

두 번째 조건을 만족하는, 개념은 사용하는 \ (C_N ^ M \) 큰 대형 M 전에 운전자 M 전과 후에 NM 별도로 설명한다 위치 수. 숫자가 동일 할 수 있기 때문에, 그래서 (큰 M은 NM와 같은 번호가있을 수 있습니다 전에 즉, 서로 영향을 미치는 경우) 반복 계산.
그러나, 만약 차례로, 그래서 우리는 종류 A '[M] ≠ A' [M + 1]. 정렬 때문에, A '[M]> A'그래서 [M + 1] 전후 큰 M은 NM을 분리되도록.
프로그램의 수를 계산함으로써 제한없이 프로그램 번호, 강제 같지 않은 - 프로그램의 수는 힘에 응답 할 수 같지 않다.

지금 청구항의 수를 제한하는 변환 열거 A [M] = X를, 시퀀스 M> = X, 나머지가 N - M <x의 개수를, 적어도 하나의 수 = X를 갖는다. 마지막 계수가 곱해질 수있다 (\ C_N ^ M은 \) 그 중은> = X 선택의 수를 나타낸다.
그는 마지막 조건은 눈에 거슬리는이지만 카운트 중복을 제거 할 수 있다면 것을 말한다.
우리는이 방식으로 처리 "숫자 M> = X, N - M <프로그램 X의 수의 수"로 감산 "M 번호> X, N - M <프로그램에서 x의 수", 즉 재사용 용량 배제.

이제 문제로 : A1 + A2 + ... + + B = S, A [1], A [2], ... A [M]> = P 0 <= A [M + 1] A [M + 2], ... 프로그램 A [N] <Q의 수.
제한은 [1], A는 [2 ], ... A는 [M]는> = p는 S 개의 M의 * p를 감산하여 사전에 처리 될 수 있으므로 수는 A [1 ... M]는 하한값진다 0.
제한 A [M + 1]하는 [M + 2], ... A [N] <q를 포함 및 배제가 사용될 수 있으며, 열거 강제 K로부터 선택된 수> = Q는 S 감산 K * Q 그런 다음 동일한 그것은 제로 하한이된다. 인자 승산 \을 (NM C_ {} ^ { K}는 \) 선택 (K)의 수를 나타낸다.

마지막으로, 시간 복잡도에 대한 때문에 S로 - 0 * 의미 전율의 Q> =, 최종 포함 및 배제 O가되도록 (S / Q) 복잡한 계산 다른 일정한 레벨.
및 q는 1 번에서 열거 ... K는 시간 복잡도는 O (S / S + 1 / 2 + ... + S / K). S 및 O 약 간주 될 수와 동일한 순서의 K (K는 K 로그).

@accepted 코드 @

#include<cstdio>
const int MAXN = 1000000;
const int MOD = int(1E9) + 7;
int pow_mod(int b, int p) {
    int ret = 1;
    while( p ) {
        if( p & 1 ) ret = 1LL*ret*b%MOD;
        b = 1LL*b*b%MOD;
        p >>= 1;
    }
    return ret;
}
int fct[MAXN + 5], ifct[MAXN + 5];
void init() {
    fct[0] = 1;
    for(int i=1;i<=MAXN;i++)
        fct[i] = 1LL*fct[i-1]*i%MOD;
    ifct[MAXN] = pow_mod(fct[MAXN], MOD-2);
    for(int i=MAXN-1;i>=0;i--)
        ifct[i] = 1LL*ifct[i+1]*(i+1)%MOD;
}
int comb(int n, int m) {return 1LL*fct[n]*ifct[m]%MOD*ifct[n-m]%MOD;}
int solve2(int N, int M, int S, int l, int r) {
    int ret = 0;
    if( S - 1LL*M*r < 0 ) return ret;
    else S -= M*r;
    for(int i=0,f=1;i<=N-M&&S>=0;i++,f=1LL*f*(MOD-1)%MOD,S-=l)
        ret = (ret + 1LL*f*comb(S + N, N)%MOD*comb(N - M, i)%MOD)%MOD;
    return 1LL*ret*comb(N, M)%MOD;
}
//A1 + A2 + ... + AN + B = S, A[1...M] >= r, 0 <= A[M+1...N] < l
//A1 + A2 + ... + AN + B = S - M*r, A[1...M] >= 0, 0 <= A[M+1...N] < l
int solve(int N, int M, int S) {
    int ret = comb(S + N, N);
    for(int i=S;i>=1;i--) {
        int del = (solve2(N, M, S, i, i) + MOD - solve2(N, M, S, i, i + 1))%MOD;
        ret = (ret + MOD - del)%MOD;
    }
    return ret;
}
//A1 + A2 + ... + AN + B = S
int main() {
    init(); int N, M, L, R;
    scanf("%d%d%d%d", &N, &M, &L, &R);
    printf("%d\n", (solve(N, M, R) + MOD - solve(N, M, L - 1))%MOD);
}

@세부@

경쟁 순위 느낌을 볼 때 할 수있는 문제가 아니다, 다음 테스트에 같은 아 FFT 무엇인지에 대해 생각하고있다. . .

경기가 생각 후에, 나는 아,이 숫자가 그것을 할 함께 사용하지 말아야하지 발견했다.
그리고 나는 해결책을 원하고, 마지막으로 편집 대비와 일치 발견했다. . .

제목의 유도의 모든 단계는 전체 루틴 숨을 공개했다. . .

추천

출처www.cnblogs.com/Tiw-Air-OAO/p/11406974.html