250621 유성

Jongleee·2025년 6월 21일
0

TIL

목록 보기
936/970
static final String NIE = "NIE\n";
static final char NEW_LINE = '\n';

static int m, q, count;
static FenwickTree fenwick;
static BinarySearchNode[] pendingQueries;

static class FenwickTree {
	int size;
	long[] tree, initial;

	FenwickTree(int size) {
		this.size = size;
		tree = new long[size + 2];
		initial = new long[size + 2];
	}

	void reset() {
		System.arraycopy(initial, 1, tree, 1, size);
	}

	void updateRange(int l, int r, long delta) {
		add(l, delta);
		if (r < size)
			add(r + 1, -delta);
	}

	private void add(int index, long delta) {
		while (index <= size) {
			tree[index] += delta;
			index += index & -index;
		}
	}

	long query(int index) {
		long result = 0;
		while (index > 0) {
			result += tree[index];
			index -= index & -index;
		}
		return result;
	}
}

static class Area {
	int index;
	Area next;

	Area(int index, Area next) {
		this.index = index;
		this.next = next;
	}
}

static class Query {
	int left, right;
	long value;

	Query(int left, int right, long value) {
		this.left = left;
		this.right = right;
		this.value = value;
	}

	void apply() {
		if (left <= right) {
			fenwick.updateRange(left, right, value);
		} else {
			fenwick.updateRange(left, m, value);
			fenwick.updateRange(1, right, value);
		}
	}
}

static class BinarySearchNode {
	int l = 1;
	int r = q + 1;
	int result = q + 1;
	long target;
	Area areaHead;
	BinarySearchNode next;

	BinarySearchNode(long target, BinarySearchNode next) {
		this.target = target;
		this.next = next;
	}

	void evaluate(int mid) {
		long sum = 0;
		for (Area area = areaHead; area != null; area = area.next) {
			sum += fenwick.query(area.index);
			if (sum >= target)
				break;
		}

		pendingQueries[mid] = next;
		if (sum < target) {
			l = mid + 1;
		} else {
			r = mid;
		}

		if (l >= r) {
			result = r;
			count++;
		} else {
			int newMid = (l + r) >>> 1;
			next = pendingQueries[newMid];
			pendingQueries[newMid] = this;
		}
	}
}

public static void main(String[] args) throws IOException {
	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

	StringTokenizer st = new StringTokenizer(br.readLine());
	int n = Integer.parseInt(st.nextToken());
	m = Integer.parseInt(st.nextToken());

	StringTokenizer areaTokens = new StringTokenizer(br.readLine());
	StringTokenizer goalTokens = new StringTokenizer(br.readLine());
	q = Integer.parseInt(br.readLine());

	Query[] queries = new Query[q + 1];
	for (int i = 1; i <= q; i++) {
		st = new StringTokenizer(br.readLine());
		int l = Integer.parseInt(st.nextToken());
		int r = Integer.parseInt(st.nextToken());
		long a = Integer.parseInt(st.nextToken());
		queries[i] = new Query(l, r, a);
	}

	pendingQueries = new BinarySearchNode[q + 2];
	BinarySearchNode[] answers = new BinarySearchNode[n + 1];

	int mid = (q + 2) >>> 1;
	for (int i = 1; i <= n; i++) {
		long target = Long.parseLong(goalTokens.nextToken());
		pendingQueries[mid] = new BinarySearchNode(target, pendingQueries[mid]);
		answers[i] = pendingQueries[mid];
	}

	for (int i = 1; i <= m; i++) {
		int owner = Integer.parseInt(areaTokens.nextToken());
		answers[owner].areaHead = new Area(i, answers[owner].areaHead);
	}

	fenwick = new FenwickTree(m);

	while (count < n) {
		fenwick.reset();
		for (int i = 1; i <= q; i++) {
			queries[i].apply();
			while (pendingQueries[i] != null) {
				pendingQueries[i].evaluate(i);
			}
		}
	}

	StringBuilder sb = new StringBuilder();
	for (int i = 1; i <= n; i++) {
		if (answers[i].result > q) {
			sb.append(NIE);
		} else {
			sb.append(answers[i].result).append(NEW_LINE);
		}
	}

	System.out.print(sb);
}

출처:https://www.acmicpc.net/problem/8217

0개의 댓글