티스토리 뷰

http://codeforces.com/contest/839/problem/D




문제 요약


원소의 개수가 $N$인 배열이 있다. 우리는 다음 조건을 만족하는 부분 배열(subsequence 개념)을 찾을 것이다.

  • $N$개의 원소중 $k$개를 고른다.
  • 그 $k$개의 원소의 최대공약수가 1보다 크다.

이러한 부분 배열이 있을 때, 이 배열의 값을 $k\times gcd(a_1,a_2,...,a_k)$ 이라 한다. 이 때 가능한 모든 부분 배열의 값을 더해 1e9+7로 나눈 값을 구하는 문제이다.




풀이


우리는 2개의 배열이 필요하다. $cnt[i]$와 $ans[i]$. 우선 $cnt[i]$를 모든 원소 $a_j$에 대해 $i$로 나누어 떨어지는 $a_j$의 개수라 하자. 그러니까 모든 $a_j$의 약수에 대해 cnt값을 1씩 증가시켜준다고 생각하면 된다. 그 다음 $cnt[i]=c$라 했을 때, $ans[i]$는 $\sum _{ k=1 }^{ c }{ k }\binom{c}{k}$ 값이다. $k$를 곱하는 건 문제에서 요구하는 바이고, $\binom{c}{k}$ 은 $c$개 중에서 $k$개를 고르는 경우의 수이다. 이 식을 변형해보자.



위 식을 통해 $ans[i]=cnt[i]\times 2^{cnt[i]-1}$ 임을 알 수 있다.


하지만 여기서 끝이 아니다.

$ans[2]$중에서는 $ans[4]$에 포함된 것도 있을테고 $ans[6]$에 포함된 것도 있을 것이다. 이러한 것들을 다 제거해줘야한다. 


따라서 다음과 같은 과정을 거쳐야 진짜배기 $ans[i]$를 구할 수 있다.

$ans[i] = ans[i] - ans[2*i] - ans[3*i] .... $

이러면 $ans[i]$에는 최대공약수가 $i$인 부분 배열들에 대한 정보만 남는다.


최종적으로 답은 $\sum _{ i=2 }^{ 1000000 }{ i\times ans[i]}$라는 것은 굳이 이유를 설명하지 않아도 알 수 있을 것이다. 


$T$를 $a_i$의 최대값 이라 할 때 시간복잡도는 $O(T+T/2+T/3+...) = O(TlgT)$가 된다. 시간복잡도가 이렇게 되는 이유는 이 링크에서 확인하도록.



'문제풀이' 카테고리의 다른 글

[BOJ] 15555 Dango Maker  (1) 2020.07.31
[BOJ] 14942 개미  (1) 2018.01.21
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/04   »
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 29 30
글 보관함