Loading [MathJax]/jax/output/CommonHTML/jax.js

[BOJ 13430] 합 구하기

2021. 8. 15. 18:26PS/백준

이 문제에서 구하려는 함수는 다음과 같다.

함수 S는 다음과 같이 정의된다.

  • S(0, n)=n (모든 양의 정수 n)
  • S(k, n)=S(k1, 1)+S(k1, 2)+...+S(k1, n) (모든 양의 정수 k, n)

 

이때 S(k,n)을 적절히 변형시켜보자.

S(k, n)=S(k2, 1)+[S(k2, 1)+S(k2, 2)]+[S(k2, 1)+S(k2, 2)+S(k2, 3)]+...

=nS(k2, 1)+(n1)S(k2, 2)+(n2)S(k2, 3)+...

정의에 의해서

=nS(k3, 1)+(n1)[S(k3, 1)+S(k3, 2)]+(n2)[S(k3, 1)+S(k3, 2)+S(k3, 3)]+...

각 계수를 조합으로 적절히 변형시켜주면

=nC1 S(k3, 1)+n1C1 [S(k3, 1)+S(k3, 2)]+n2C1 [S(k3, 1)+S(k3, 2)+S(k3, 3)]+...

하키스틱 정리를 적용하면

=n+1C2 S(k3, 1)+nC2 S(k3, 2)+n1C2 S(k3, 3)+...

위와 같은 과정을 반복하면

=n+pCp+1 S(kp2, 1)+n+p1Cp+1 S(kp2 ,2)+n+p2Cp+1 S(kp2, 3)+...

kp2=0이라고 한다면 p=k2이다.

이때 식은

=n+k2Ck1 S(0, 1)+n+k3Ck1 S(0 ,2)+n+k4Ck1 S(0, 3)+...

정의에 의해

=n+k2Ck1+2n+k3Ck1+3n+k4Ck1+...

이것은 조합의 뒷 숫자가 k1인 것들의 합이므로 하키스틱 정리를 이용할 수 있다. 조합의 앞 숫자가 k1인 것이 n개 존재하므로 조합의 앞 숫자가 k1인 것부터 n+k2까지, k1인 것부터 nk3까지 ... 이런 방식으로 따로 따로 하키스틱 정리를 적용시킬 수 있다. 이를 적용하면

=n+k1Ck+n+k2Ck+n+k3Ck+...

다시 하키스틱 정리를 적용하면

=n+kCk+1

S(n, k)=n+kCk+1

이제 조합을 계산하기만 하면 끝!

 

코드는 다음과 같다.

 

코드 보기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<stdio.h>
typedef long long int lo;
lo p=1e9+7;
lo pow(lo n,lo k){
    lo s=1,h=n;
    for(;k;k>>=1){
        if(k&1) s=s*h%p;
        h=h*h%p;
    }
    return s;
}
lo fac(lo n){
    lo s=1,i;
    for(i=1;i<=n;i++){
        s=s*i%p;
    }
    return s;
}
int main(){
    lo n,k,s=1,i;
    scanf("%lld %lld",&k,&n);
    for(i=n;i<=n+k;i++){
        s=s*i%p;
    }
    s=s*pow(fac(k+1),p-2)%p;
    printf("%lld",s);
}
 
cs