본문 바로가기

PS - 알고리즘

15005 - Collatz Conjecture

번역

더보기

길이 $N$인 수열 $A$가 주어집니다. $1 \le i \le j \le N$인 $i, j$에 대해서 $f(i,j) = \gcd(a_i, a_{i+1},...,a_j)$를 생각해 봅시다. 모든 $f(i,j)$가 가질 수 있는 값의 개수를 출력하시오.

step 1

더보기

$j$가 정해졌고 $i$가 $j$부터 하나씩 감소한다고 생각해 봅시다. 처음에는 $\gcd(a_j)$이니 당연히 $a_j$일 것입니다. 다음은 $\gcd(a_{j-1}, a_j)$, 다음은 $\gcd(a_{j-2}, a_{j-1}, a_j)$가 될 것입니다. 이때, $f(i,j)$는 계속해서 감소하고 $f(i,j)$가 변하는 지점은 많아야 $\log_2 {a_j}$입니다.

step 2

더보기

$i$가 $N$부터 1까지 감소하고 각 $i$마다 $j$가 $i$부터 $N$까지 증가한다고 해봅시다. 만약 $f(i, j)=f(i+1, j)$라면 $f(i, j+1)=f(i+1, j+1)$이므로 더 이상 진행하지 않아도 됩니다.

코드

더보기
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<set>
using namespace std;
set<long long int> ss;
long long int ch[500010],b[500010];
long long int gcd(long long int x, long long int y) { return y == 0 ? x : gcd(y, x % y); }
int main() {
	int n, i,j;
	scanf("%d", &n);
	for (i = 1;i <= n;i++) {
		scanf("%lld", &b[i]);
		ch[i] = 0;
	}
	for (i = n;i >= 1;i--) {
		long long int g = b[i];
		ss.insert(g);
		ch[i] = g;
		for (j = i+1;j <= n;j++) {
			g = gcd(g, b[j]);
			if (ch[j] == g) break;
			ch[j] = g;
			ss.insert(g);
		}
	}
	printf("%d", ss.size());
	return 0;
}

'PS - 알고리즘' 카테고리의 다른 글

12877 - 먹이 사슬  (0) 2024.11.11
13215 - Fish  (0) 2024.10.21
11025 - 요세푸스 문제 3  (0) 2024.10.14
23755 - 카드컨트롤 (Hard)  (0) 2024.10.07
24520 - Meet In The Middle  (0) 2024.09.30