Submission #506092

#TimeUsernameProblemLanguageResultExecution timeMemory
506092mmaxio가로등 (APIO19_street_lamps)Java
100 / 100
2646 ms288656 KiB
import java.io.*; import java.math.*; import java.util.*; import java.util.stream.*; public class street_lamps { int n; ArrayList<Integer>[] fensPtsALs; int[][] fensPts; int[][] fens; int[] qLog = new int[300_000 * 3 * 19]; int qPtr = 0; int[] outp; void modify(int l, int r, int val) { r = n - 1 - r; qLog[qPtr++] = l; qLog[qPtr++] = r; qLog[qPtr++] = val; } void query(int l, int r, int qIdx) { // sum over points with L <= l, R >= r r = n - 1 - r; for (int i = l; i >= 0; i = (i & (i + 1)) - 1) { fensPtsALs[i].add(r); } qLog[qPtr++] = ~l; qLog[qPtr++] = r; qLog[qPtr++] = qIdx; } void prepareQs() { for (int i = 0; i < n; i++) { ArrayList<Integer> lst = fensPtsALs[i]; Collections.sort(lst); int sz = 0; for (int j = 0; j < lst.size(); j++) { if (j == 0 || !lst.get(j).equals(lst.get(j - 1))) { sz++; } } int[] arr = fensPts[i] = new int[sz]; for (int j = 0, k = 0; j < lst.size(); j++) { if (j == 0 || !lst.get(j).equals(lst.get(j - 1))) { arr[k++] = lst.get(j); } } fens[i] = new int[sz]; } } void executeQs() { for (int z = 0; z < qPtr; z += 3) { int l = qLog[z]; int r = qLog[z + 1]; int val = qLog[z + 2]; if (l >= 0) { for (int i = l; i < n; i |= i + 1) { int[] f = fens[i]; int compR = Arrays.binarySearch(fensPts[i], r); if (compR < 0) { compR = -compR - 1; } for (int j = compR; j < f.length; j |= j + 1) { f[j] += val; } } } else { l = ~l; int result = outp[val]; for (int i = l; i >= 0; i = (i & (i + 1)) - 1) { int[] f = fens[i]; int compR = Arrays.binarySearch(fensPts[i], r); if (compR < 0) { throw new AssertionError(); } for (int j = compR; j >= 0; j = (j & (j + 1)) - 1) { result += f[j]; } } out.println(result); } } } void submit() { n = nextInt(); fensPtsALs = new ArrayList[n]; fensPts = new int[n][]; fens = new int[n][]; for (int i = 0; i < n; i++) { fensPtsALs[i] = new ArrayList<>(); } int q = nextInt(); outp = new int[q]; String ss = nextToken(); int[] s = new int[n]; for (int i = 0; i < n; i++) { s[i] = ss.charAt(i) - '0'; } int[] jump = new int[n]; int[] from = new int[n]; TreeSet<Integer> lefts = new TreeSet<>(); for (int i = 0; i < n; i++) { if (s[i] == 1) { int j = i + 1; while (j < n && s[j] == 1) { j++; } jump[i] = j - 1; jump[j - 1] = i; lefts.add(i); from[i] = 0; i = j; } } for (int i = 1; i <= q; i++) { String cmd = nextToken(); if (cmd.equals("toggle")) { int idx = nextInt() - 1; if (s[idx] == 0) { int newL; if (idx - 1 >= 0 && s[idx - 1] == 1) { int r = idx - 1; int l = jump[r]; modify(l, r, i - from[l]); newL = l; if (!lefts.remove(l)) { throw new AssertionError(); } } else { newL = idx; } int newR; if (idx + 1 < n && s[idx + 1] == 1) { int l = idx + 1; int r = jump[l]; modify(l, r, i - from[l]); newR = r; if (!lefts.remove(l)) { throw new AssertionError(); } } else { newR = idx; } if (!lefts.add(newL)) { throw new AssertionError(); } jump[newL] = newR; jump[newR] = newL; from[newL] = i; } else { int l = lefts.floor(idx); int r = jump[l]; modify(l, r, i - from[l]); if (!lefts.remove(l)) { throw new AssertionError(); } if (idx != l) { int newL = l; int newR = idx - 1; if (!lefts.add(newL)) { throw new AssertionError(); } jump[newL] = newR; jump[newR] = newL; from[newL] = i; } if (idx != r) { int newL = idx + 1; int newR = r; if (!lefts.add(newL)) { throw new AssertionError(); } jump[newL] = newR; jump[newR] = newL; from[newL] = i; } } s[idx] ^= 1; } else if (cmd.equals("query")) { int l = nextInt() - 1; int r = nextInt() - 2; if (s[l] == 1) { int left = lefts.floor(l); // can't be null because we check if it's active int right = jump[left]; if (right >= r) { outp[i - 1] += i - from[left]; } } query(l, r, i - 1); } } prepareQs(); executeQs(); } void test() { } void stress() { for (int tst = 0;; tst++) { if (false) { throw new AssertionError(); } System.err.println(tst); } } street_lamps() throws IOException { is = System.in; out = new PrintWriter(System.out); submit(); // stress(); // test(); out.close(); } static final Random rng = new Random(); static final int C = 5; static int rand(int l, int r) { return l + rng.nextInt(r - l + 1); } public static void main(String[] args) throws IOException { new street_lamps(); } private InputStream is; PrintWriter out; private byte[] buf = new byte[1 << 14]; private int bufSz = 0, bufPtr = 0; private int readByte() { if (bufSz == -1) throw new RuntimeException("Reading past EOF"); if (bufPtr >= bufSz) { bufPtr = 0; try { bufSz = is.read(buf); } catch (IOException e) { throw new RuntimeException(e); } if (bufSz <= 0) return -1; } return buf[bufPtr++]; } private boolean isTrash(int c) { return c < 33 || c > 126; } private int skip() { int b; while ((b = readByte()) != -1 && isTrash(b)) ; return b; } String nextToken() { int b = skip(); StringBuilder sb = new StringBuilder(); while (!isTrash(b)) { sb.appendCodePoint(b); b = readByte(); } return sb.toString(); } String nextString() { int b = readByte(); StringBuilder sb = new StringBuilder(); while (!isTrash(b) || b == ' ') { sb.appendCodePoint(b); b = readByte(); } return sb.toString(); } double nextDouble() { return Double.parseDouble(nextToken()); } char nextChar() { return (char) skip(); } int nextInt() { int ret = 0; int b = skip(); if (b != '-' && (b < '0' || b > '9')) { throw new InputMismatchException(); } boolean neg = false; if (b == '-') { neg = true; b = readByte(); } while (true) { if (b >= '0' && b <= '9') { ret = ret * 10 + (b - '0'); } else { if (b != -1 && !isTrash(b)) { throw new InputMismatchException(); } return neg ? -ret : ret; } b = readByte(); } } long nextLong() { long ret = 0; int b = skip(); if (b != '-' && (b < '0' || b > '9')) { throw new InputMismatchException(); } boolean neg = false; if (b == '-') { neg = true; b = readByte(); } while (true) { if (b >= '0' && b <= '9') { ret = ret * 10 + (b - '0'); } else { if (b != -1 && !isTrash(b)) { throw new InputMismatchException(); } return neg ? -ret : ret; } b = readByte(); } } }

Compilation message (stderr)

Note: street_lamps.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...