https://coderun.yandex.ru/problem/ngu-building/description Сложная

Решение

import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class J {
    public static void main(String[] args) throws IOException {
        try (InputStream reader = new BufferedInputStream(System.in, 3_000_000);
             BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out))) {
            alg(reader, writer);
        }
    }

    public static void alg(InputStream is, BufferedWriter writer) throws IOException {
        Reader reader = new Reader(is);
        int n = reader.nextInt();
        int requiredSquare = reader.nextInt() * reader.nextInt();
        int[] z1 = new int[n];
        int[] z2 = new int[n];
        int[] s = new int[n];
        for (int i = 0; i < n; i++) {
            int x1 = reader.nextInt();
            int y1 = reader.nextInt();
            z1[i] = reader.nextInt();
            int x2 = reader.nextInt();
            int y2 = reader.nextInt();
            z2[i] = reader.nextInt();
            s[i] = (x2 - x1) * (y2 - y1);
        }

        String solution = alg1(n, requiredSquare, z1, z2, s);

        writer.write(solution);
        writer.flush();
    }

    static class Event implements Comparable<Event> {
        enum Type {Z2, Z1}

        final Type type;
        final int z;
        final int block;

        Event(Type type, int z, int block) {
            this.type = type;
            this.z = z;
            this.block = block;
        }

        @Override
        public int compareTo(Event e) {
            int c = Integer.compare(z, e.z);
            if (c == 0)
                c = Integer.compare(type.ordinal(), e.type.ordinal());
            return c;
        }
    }

    static List<Event> events(int n, int[] z1, int[] z2) {
        List<Event> events = new ArrayList<>(n);
        for (int i = 0; i < n; i++) {
            events.add(new Event(Event.Type.Z1, z1[i], i));
            events.add(new Event(Event.Type.Z2, z2[i], i));
        }
        events.sort(Event::compareTo);
        return events;
    }

    public static String alg1(int n, int requiredSquare, int[] z1, int[] z2, int[] s) {
        List<Event> events = events(n, z1, z2);

        Set<Integer> minCountGluedBlocks = IntStream.range(0, n + 1).boxed().collect(Collectors.toSet());
        Set<Integer> curGluedBlocks = new HashSet<>(n);
        int gluedBlockSquare = 0;
        for (Event e : events) {
            if (e.type == Event.Type.Z1) {
                curGluedBlocks.add(e.block);
                gluedBlockSquare += s[e.block];

                if (gluedBlockSquare == requiredSquare && curGluedBlocks.size() < minCountGluedBlocks.size()) {
                    minCountGluedBlocks.clear();
                    minCountGluedBlocks.addAll(curGluedBlocks);
                }

            } else {
                curGluedBlocks.remove(e.block);
                gluedBlockSquare -= s[e.block];
            }
        }

        StringBuilder sb = new StringBuilder();
        if (minCountGluedBlocks.size() <= n) {
            sb.append("YES").append('\\n');
            sb.append(minCountGluedBlocks.size()).append('\\n');
            minCountGluedBlocks.stream().sorted().forEach(block -> sb.append(block + 1).append('\\n'));
        } else {
            sb.append("NO");
        }
        return sb.toString();
    }

    public static class Reader {
        private final InputStream is;
        private int lastReadByte = '\\n';

        public Reader(InputStream is) {
            this.is = is;
        }

        public long nextLong() throws IOException {
            while (lastReadByte == ' ' || lastReadByte == '\\n') {
                lastReadByte = is.read();
            }

            int sign = 1;
            if (lastReadByte == '-') {
                sign = -1;
                lastReadByte = is.read();
            }

            long num = 0;
            while (lastReadByte >= '0' && lastReadByte <= '9') {
                num = (num * 10) + sign * (lastReadByte - '0');
                lastReadByte = is.read();
            }
            return num;
        }

        public long[] nextLongs(long[] a) throws IOException {
            for (int i = 0; i < a.length; i++) {
                a[i] = nextLong();
            }
            return a;
        }

        public int nextInt() throws IOException {
            return (int) nextLong();
        }

        public int[] nextInts(int[] a) throws IOException {
            for (int i = 0; i < a.length; i++) {
                a[i] = nextInt();
            }
            return a;
        }

        public String nextWord() throws IOException {
            while (lastReadByte == ' ' || lastReadByte == '\\n') {
                lastReadByte = is.read();
            }

            StringBuilder sb = new StringBuilder();
            while (!(lastReadByte == -1 || lastReadByte == ' ' || lastReadByte == '\\n')) {
                sb.append((char) lastReadByte);
                lastReadByte = is.read();
            }
            return sb.toString();
        }

        public String[] nextWords(String[] a) throws IOException {
            for (int i = 0; i < a.length; i++) {
                a[i] = nextWord();
            }
            return a;
        }

        public String readLine() throws IOException {
            if (lastReadByte == '\\n') {
                lastReadByte = is.read();
            }

            StringBuilder sb = new StringBuilder();
            while (!(lastReadByte == -1 || lastReadByte == '\\n')) {
                sb.append((char) lastReadByte);
                lastReadByte = is.read();
            }
            return sb.toString();
        }
    }
}