====== Milk Sum ====== ===== 풀이 ===== * 처음 주어진 상태에서 최대로 우유를 생산하는 방법은, 생산량이 많은 소를 가장 오랫동안 짜는 것이다. 소들을 정렬해놓고 앞에서부터 x1,x2,x3,... 을 해서 더한값이 총 생산량이 된다. * 값이 바뀌어도 이 원칙은 동일하다. 어떤 소의 생산량이 변경된다면 다시 정렬해서 똑같이 구하면 최대 생산량을 구할수 있다. * 하지만, 바뀐 원소가 하나라며 전체를 다시 정렬할 필요도 없다. 어떤 소의 생산량이 x에서 y로 변했다고 하자. 원래 x가 몇번째였는지, 그리고 y가 몇번째인지는 이분탐색으로 찾을수 있다. x는 i번째, y는 j번째라고 할때, 변경되는 값만 구해주면 된다. 우선 원래 생산량에서 x*i를 빼고, y*j를 더해줘야 한다. 그리고 j """Solution code for "BOJ 28031. Milk Sum". - Problem link: https://www.acmicpc.net/problem/28031 - Solution link: http://www.teferi.net/ps/problems/boj/28031 Tags: [prefix sum] [binary search] """ import bisect import sys def main(): N = int(sys.stdin.readline()) # pylint: disable=unused-variable a = [int(x) for x in sys.stdin.readline().split()] sorted_cows = sorted(a) prefix_sum = [v := 0] + [v := v + x for x in sorted_cows] total_milk = sum(i * x for i, x in enumerate(sorted_cows, start=1)) Q = int(sys.stdin.readline()) for _ in range(Q): i, j = [int(x) for x in sys.stdin.readline().split()] cur_milk, next_milk = a[i - 1], j cur_pos = bisect.bisect_left(sorted_cows, cur_milk) next_pos = ( bisect.bisect_left(sorted_cows, j) if next_milk <= cur_milk else bisect.bisect_right(sorted_cows, j) - 1 ) answer = ( total_milk - cur_milk * (cur_pos + 1) + next_milk * (next_pos + 1) ) if next_pos > cur_pos: answer -= prefix_sum[next_pos + 1] - prefix_sum[cur_pos + 1] else: answer += prefix_sum[cur_pos] - prefix_sum[next_pos] print(answer) if __name__ == '__main__': main() {{tag>BOJ ps:problems:boj:골드_2}}