※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 20305번 문제인 피보나치와 수열과 쿼리이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/20305
20305번: 피보나치와 수열과 쿼리
모든 쿼리를 적용한 후, 수열의 모든 수를 공백으로 구분해 출력한다. 단, 수가 너무 커질 수 있으니 각각의 수를 $10^9+7$으로 나눈 나머지를 출력한다.
www.acmicpc.net
이 문제를 풀기 위해 관찰해야할 것은 다음 두 가지이다.
1) 모든 쿼리를 처리한 이후의 최종 결과만을 출력하면 된다. 또한, 이 문제에서 주어지는 쿼리는 순서를 바꿔서 계산해도 최종 결과가 변하지 않는다. (단순한 덧셈이므로)
2) 피보나치 수의 특징을 생각하여, 각 쿼리를 입력받아 시작점, 끝점에 1과 쿼리 구간길이에 대응되는 적절한 피보나치수를 구간의 끝에서 빼주는 것으로 미리 전부 업데이트를 하고 피보나치 점화관계를 이용하여 수열을 구해낼 수 있다.
아래는 제출한 소스코드이다.
#include <iostream>
using namespace std;
typedef long long ll;
ll fib[1000011];
ll arr[1000011];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
fib[1] = fib[2] = 1;
int N, Q; cin >> N >> Q;
for (int i = 3; i <= 1000010; i++) {
fib[i] = (fib[i - 1] + fib[i - 2])%1000000007;
}
while (Q--) {
int x, y; cin >> x >> y;
arr[x] += 1;
arr[y + 1] -= fib[y - x + 2];
arr[y + 2] -= fib[y - x + 1];
}
for (int i = 1; i <= N; i++) {
cout << arr[i] << ' ';
arr[i + 1] += arr[i-1] + arr[i];
arr[i + 1] %= 1000000007;
if (arr[i + 1] < 0) arr[i + 1] += 1000000007;
}
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 16928 // C++] 뱀과 사다리 게임 (0) | 2021.06.27 |
---|---|
[BOJ 12852 // C++] 1로 만들기 2 (0) | 2021.06.26 |
[BOJ 16953 // C++] A → B (0) | 2021.06.24 |
[BOJ 5000 // C++] 빵 정렬 (0) | 2021.06.23 |
[BOJ 5002 // C++] 도어맨 (0) | 2021.06.22 |