Задать вопрос
BitNeBolt
@BitNeBolt

Почему не получается найти подпоследовательность?

Добрый вечер. В задаче требуется проверить, является ли массив подпоследовательностью другого на отрезке [l; r]. Все мои решения (одно обычное, линейное, другое чуть быстрее) ломаются, набрав 40 баллов, а вердикт мне неизвестен (мне кажется, что тля).

Вот то, что побыстрее, основано на индексах

import java.util.*;
import java.io.*;

public class D {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		var inds = new HashMap<Integer, List<Integer>>();

		int n = sc.nextInt();
		for (int i = 0; i < n; i++) {
			int x = sc.nextInt();
			var adjs = inds.getOrDefault(x, new ArrayList<Integer>());
			adjs.add(i);
			inds.put(x, adjs);
		}

		int q = sc.nextInt();
		for (; q > 0; q--) {
			int l = sc.nextInt()-1; 
			int r = sc.nextInt()-1;
			int m = sc.nextInt();

			boolean ok = true;

			var b = new int[m];
			for (int i = 0; i < m; i++) {
				b[i] = sc.nextInt();
			}

			int prev = -1;
			for (int i = 0; i < m; i++) {
				int next = -1;
				int x = b[i];

				if (!inds.keySet().contains(x)) {
					ok = false;
					break;
				}

				var adjs = inds.get(x);
				for (int j = 0; j < adjs.size(); j++) {
					int ind = adjs.get(j);
					if (ind > prev && ind >= l && ind <= r) {
						next = ind;
						break;
					}
				}

				if (next == -1) {
					ok = false;
					break;
				} else {
					prev = next;
				}
			}

			out.println(ok ? "YES" : "NO");
		}

		out.close();
		sc.close();
	}
}



Может ли это решение вообще TLE-шиться, оно же линейно? В чем может быть ошибка?
  • Вопрос задан
  • 106 просмотров
Подписаться 1 Простой 1 комментарий
Решения вопроса 1
wataru
@wataru Куратор тега Алгоритмы
Разработчик на С++, экс-олимпиадник.
У вас решение за O(MN), когда как можно за O(M log N).

Вы говорите, что оно линейно, но вы выполняете линейное количество операций на каждый элемент массива b. Это медленно. Ваша проблема в том, что вы храните все индексы для каждого значения просто в списке и потом там наивно ищите первое вхождение больше данной границы. Можно список хранить в Set. Вот я не в курсе, умеет ли он, как C++-шный set искать первый элемент больше заданной границы. Если нет, то можно тупо хранить отсортированые списки индексов, тогда там можно будет делать бинпоиск.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы