코드포스

[Hello 2023] C. Least Prefix Sum

거북이같은곰 2023. 1. 5. 22:51

 

 


※. pm까지의 누적합이 가장 작아야 한다.

(pm+1 ~ pn까지의 합이 0이하가 되면 안된다. -> pm 이후의 누적합을 sum이라 할 때 sum이 음수가 된다면 (pm + 음수)로

pm보다 작은값이 생기기 때문)

 ● pm+1부터 pn까지 누적합을 구하다 누적합이 0미만이 되는 순간이 있으면 누적합이 양수가 될 때 까지 우선순위큐에서     값을 빼 더해준다.

   (원소값이 양수라면 0미만이 될 수 없으므로 제외, 원소값이 음수라면 0미만이 될 수 있기 때문에 누적합에 더해주고 이     후에 누적합이 0미만이 되면 누적합 - 더해준 원소값 +(-더해준 원소값)을 해줘야 함으로 (-2*arr[i])로 우선순위큐에 넣는     다.)

 

※.pm을 포함한 이전의 누적합은 원소값보다 커야한다.

(pm이전의 누적합들은 pm까지의 누적합보다 커야한다. -> pm을 포함한 누적합이 가장 작아야 함으로 음수가 나올수록 누적합이 계속 작아진다. 그러나 양수가 나올 경우 pm을 포함한 누적합이 커지면서 어느순간 원소값이 누적합보다 작아지는 경우가 생긴다. 이 때 가장 큰 양수를 -로 변환함으로써 누적합을 작게 만든다.)

 ●pm부터 p1까지의 누적합을 구하다 누적합이 원소값보다 큰 경우가 생기면 누적합이 원소값보다 작아질때 까지 우선순위큐에서 값을 빼 더해준다.

 (원소값이 음수라면 pm을 포함한 누적합이 계속 작아지므로 제외, 원소값이 양수라면 pm을 포함한 누적합이 커지고 가장 작은 수가 아닐수도 있기 때문에 누적합이 원소값보다 크다면 누적합 - (양수원소값) + (음수로 변환된 양수원소값) 을 해줘서 누적합을 작게 만들어 준다. 때문에 양수 원소값은 (-2*arr[i])로 우선순위큐에 넣는다.)

 

 


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Collections;
import java.util.PriorityQueue;
import java.util.StringTokenizer;


public class Main {
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb = new StringBuilder();
		int T = Integer.parseInt(br.readLine());
		while(T --> 0) {
			StringTokenizer st = new StringTokenizer(br.readLine()," ");
			int n =  Integer.parseInt(st.nextToken());
			int m = Integer.parseInt(st.nextToken());
			int[] arr = new int[n];
			st = new StringTokenizer(br.readLine()," ");
			for(int i = 0; i < n; i++) {
				arr[i] = Integer.parseInt(st.nextToken());
			}
			PriorityQueue<Long> prque = new PriorityQueue<>(Collections.reverseOrder());
			long ans = 0;
			long sum = 0;
			for(int i = m; i < n; i++) {
				sum += arr[i];
				if(arr[i] < 0) {
					prque.add(-2*(long)arr[i]);
				}
				while(prque.size() > 0 && sum < 0) {
					sum += prque.poll();
					ans++;
				}
			}
			
			sum = 0;
			prque = new PriorityQueue<>();
			for(int i = m-1; i >= 0; i--) {
				sum += arr[i];
				while(prque.size() > 0 && arr[i] < sum) {
					sum += prque.poll();
					ans++;
				}
				if(arr[i] > 0) {
					prque.add(-2*(long)arr[i]);
				}
			}
			if(n == 1)
				ans = 0;
			sb.append(ans).append('\n');
		}
		System.out.println(sb);
	}
}