import java.io.OutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.util.HashMap; import java.io.IOException; import java.io.InputStreamReader; import java.util.TreeSet; import java.util.StringTokenizer; import java.util.Map; import java.io.BufferedReader; import java.util.Comparator; import java.io.InputStream; /** * Built using CHelper plug-in * Actual solution is at the top */ public class sze { public static void main(String[] args) { InputStream inputStream = System.in; OutputStream outputStream = System.out; InputReader in = new InputReader(inputStream); PrintWriter out = new PrintWriter(outputStream); SzeregowanieZadan solver = new SzeregowanieZadan(); solver.solve(1, in, out); out.close(); } static class SzeregowanieZadan { public void solve(int testNumber, InputReader in, PrintWriter out) { int N = in.nextInt(); int M = in.nextInt(); int P[] = new int[N]; int K[] = new int[N]; int C[] = new int[N]; for (int i = 0; i < N; i++) { P[i] = in.nextInt(); K[i] = in.nextInt(); C[i] = in.nextInt(); } // boolean ans = solutionBrute(N, M, P, K, C); boolean ans = new Optimal2().solution(N, M, P, K, C); if (!ans) { out.println("NIE"); } else { out.println("TAK"); } } private class Optimal2 { private final Comparator<Zadanie> zadanieComparator = (z1, z2) -> { if (z1.spare < z2.spare) return -1; if (z1.spare > z2.spare) return +1; if (z1.right < z2.right) return -1; if (z1.right > z2.right) return +1; if (z1.remaining > z2.remaining) return -1; if (z1.remaining < z2.remaining) return +1; return z1.idx - z2.idx; }; private Map<Integer, Odcinek> odcinkiMap; private TreeSet<Odcinek> odcinki; private TreeSet<Zadanie> zadania; private boolean solution(int n, int m, int[] p, int[] k, int[] c) { int unfinished = n; zadania = new TreeSet<>(zadanieComparator); odcinki = new TreeSet<>((o1, o2) -> { if (o1.tasks < o2.tasks) return -1; if (o1.tasks > o2.tasks) return +1; return o1.left - o2.left; }); odcinkiMap = new HashMap<>(); for (int i = 0; i < n; i++) { Zadanie zd = new Zadanie(i, p[i], k[i], c[i]); for (int j = p[i]; j < k[i]; j++) { final int finalJ = j; odcinkiMap.compute(j, (key, v) -> { if (v == null) { v = new Odcinek(finalJ, m); } v.tasks++; return v; }); } zadania.add(zd); } for (Odcinek od : odcinkiMap.values()) { odcinki.add(od); } while (!odcinki.isEmpty()) { Odcinek od = odcinki.pollFirst(); TreeSet<Zadanie> tasks = new TreeSet<>(zadanieComparator); for (Zadanie zd : zadania) { if (zd.left <= od.left && od.left + 1 <= zd.right) { tasks.add(zd); } } while (od.availableProcessors > 0 && !tasks.isEmpty()) { Zadanie best = tasks.pollFirst(); best.remaining--; if (best.remaining == 0) { zadania.remove(best); unfinished--; } od.availableProcessors--; } for (Zadanie zd : tasks) { if (--zd.spare < 0) { return false; } } } return unfinished == 0; } private class Zadanie { private int idx; private int left; private int right; private int remaining; private int spare; public Zadanie(int idx, int left, int right, int remaining) { this.idx = idx; this.left = left; this.right = right; this.remaining = remaining; this.spare = right - left - remaining; } public String toString() { return "Zadanie{" + "idx=" + idx + ", left=" + left + ", right=" + right + ", remaining=" + remaining + ", spare=" + spare + '}'; } } private class Odcinek { private int left; private int tasks; private int availableProcessors; public Odcinek(int left, int availableProcessors) { this.left = left; this.availableProcessors = availableProcessors; } } } } static class InputReader { public BufferedReader reader; public StringTokenizer tokenizer; public InputReader(InputStream stream) { reader = new BufferedReader(new InputStreamReader(stream), 32768); tokenizer = null; } public String next() { while (tokenizer == null || !tokenizer.hasMoreTokens()) { try { tokenizer = new StringTokenizer(reader.readLine()); } catch (IOException e) { throw new RuntimeException(e); } } return tokenizer.nextToken(); } public int nextInt() { return Integer.parseInt(next()); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | import java.io.OutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.util.HashMap; import java.io.IOException; import java.io.InputStreamReader; import java.util.TreeSet; import java.util.StringTokenizer; import java.util.Map; import java.io.BufferedReader; import java.util.Comparator; import java.io.InputStream; /** * Built using CHelper plug-in * Actual solution is at the top */ public class sze { public static void main(String[] args) { InputStream inputStream = System.in; OutputStream outputStream = System.out; InputReader in = new InputReader(inputStream); PrintWriter out = new PrintWriter(outputStream); SzeregowanieZadan solver = new SzeregowanieZadan(); solver.solve(1, in, out); out.close(); } static class SzeregowanieZadan { public void solve(int testNumber, InputReader in, PrintWriter out) { int N = in.nextInt(); int M = in.nextInt(); int P[] = new int[N]; int K[] = new int[N]; int C[] = new int[N]; for (int i = 0; i < N; i++) { P[i] = in.nextInt(); K[i] = in.nextInt(); C[i] = in.nextInt(); } // boolean ans = solutionBrute(N, M, P, K, C); boolean ans = new Optimal2().solution(N, M, P, K, C); if (!ans) { out.println("NIE"); } else { out.println("TAK"); } } private class Optimal2 { private final Comparator<Zadanie> zadanieComparator = (z1, z2) -> { if (z1.spare < z2.spare) return -1; if (z1.spare > z2.spare) return +1; if (z1.right < z2.right) return -1; if (z1.right > z2.right) return +1; if (z1.remaining > z2.remaining) return -1; if (z1.remaining < z2.remaining) return +1; return z1.idx - z2.idx; }; private Map<Integer, Odcinek> odcinkiMap; private TreeSet<Odcinek> odcinki; private TreeSet<Zadanie> zadania; private boolean solution(int n, int m, int[] p, int[] k, int[] c) { int unfinished = n; zadania = new TreeSet<>(zadanieComparator); odcinki = new TreeSet<>((o1, o2) -> { if (o1.tasks < o2.tasks) return -1; if (o1.tasks > o2.tasks) return +1; return o1.left - o2.left; }); odcinkiMap = new HashMap<>(); for (int i = 0; i < n; i++) { Zadanie zd = new Zadanie(i, p[i], k[i], c[i]); for (int j = p[i]; j < k[i]; j++) { final int finalJ = j; odcinkiMap.compute(j, (key, v) -> { if (v == null) { v = new Odcinek(finalJ, m); } v.tasks++; return v; }); } zadania.add(zd); } for (Odcinek od : odcinkiMap.values()) { odcinki.add(od); } while (!odcinki.isEmpty()) { Odcinek od = odcinki.pollFirst(); TreeSet<Zadanie> tasks = new TreeSet<>(zadanieComparator); for (Zadanie zd : zadania) { if (zd.left <= od.left && od.left + 1 <= zd.right) { tasks.add(zd); } } while (od.availableProcessors > 0 && !tasks.isEmpty()) { Zadanie best = tasks.pollFirst(); best.remaining--; if (best.remaining == 0) { zadania.remove(best); unfinished--; } od.availableProcessors--; } for (Zadanie zd : tasks) { if (--zd.spare < 0) { return false; } } } return unfinished == 0; } private class Zadanie { private int idx; private int left; private int right; private int remaining; private int spare; public Zadanie(int idx, int left, int right, int remaining) { this.idx = idx; this.left = left; this.right = right; this.remaining = remaining; this.spare = right - left - remaining; } public String toString() { return "Zadanie{" + "idx=" + idx + ", left=" + left + ", right=" + right + ", remaining=" + remaining + ", spare=" + spare + '}'; } } private class Odcinek { private int left; private int tasks; private int availableProcessors; public Odcinek(int left, int availableProcessors) { this.left = left; this.availableProcessors = availableProcessors; } } } } static class InputReader { public BufferedReader reader; public StringTokenizer tokenizer; public InputReader(InputStream stream) { reader = new BufferedReader(new InputStreamReader(stream), 32768); tokenizer = null; } public String next() { while (tokenizer == null || !tokenizer.hasMoreTokens()) { try { tokenizer = new StringTokenizer(reader.readLine()); } catch (IOException e) { throw new RuntimeException(e); } } return tokenizer.nextToken(); } public int nextInt() { return Integer.parseInt(next()); } } } |