https://www.acmicpc.net/problem/1280
&Title
1280번 - 나무 심기
&Question
1번부터 N번까지 번호가 매겨져 있는 N개의 나무가 있다.
i번 나무는 좌표 X[i]에 심어질 것이다.동호는 나무를 1번 나무부터
차례대로 좌표 X[i]에 심으려고 한다. 1번 나무를 심는 비용은
없고, 각각의 나무를 심는데 드는 비용은 현재 심어져있는 모든
나무 까지 거리의 합이다. 만약 3번 나무를 심는다면, 1번
나무와의 거리 + 2번 나무와의 거리가 3번 나무를 심는데
드는 비용이다.2번 나무부터 N번 나무까지를 심는 비용의 곱을 출력하는
프로그램을 작성하시오.
&Input
첫째 줄에 나무의 개수 N (2 ≤ N
≤ 200,000)이 주어진다. 둘째 줄부터 N개의 줄에 1번 나무의
좌표부터 차례대로 주어진다. 각각의 좌표는 200,000보다 작은 자연수 또는
0이다.
&Output
문제의 정답을 1,000,000,007로 나눈 나머지를 출력한다.
&Example
-input
5
3
4
5
6
7
-output
180
요약
심었던 나무들에 대한 abs(기존 나무와의 위치 - 현재 심으려는 나무 자리)의 합을 구한다.
각 나무을 심을때 비용의 곱을 구해라
접근
거리를 합으로 하는 합 세그를 구현한다.
풀이
처음에는 심었던 나무가 없으니 비용이 0으로 고정이다. 그냥 update 해준다.
심을 나무 위치 기준으로 왼쪽, 오른쪽으로 세그합 쿼리를 날려준다.
update(1, k, 0, MAXN);
for (int i = 2; i <= n; ++i) {
cin >> k;
node left = query(1, 0, (k - 1 < 0 ? 0 : k - 1), 0, MAXN);
node right = query(1, (k + 1 > MAXN ? MAXN : k + 1), MAXN, 0, MAXN);
long long q = ((long long)k * left.cnt - left.val + right.val - (long long)k * right.cnt)%MOD;
res = (res * q) % MOD;
update(1, k, 0, MAXN);
}
몇개의 나무의 합에 대한 쿼리인지 알 수 없기 때문에 struct를 통해 합한 나무 개수, 총합을 반환하여 아래와 같은 공식을 이용한다.(이러면 자연스럽게 같은 위치에 나무를 심는 경우도 처리 된다.)
댓글남기기