Submission #143172

#TimeUsernameProblemLanguageResultExecution timeMemory
143172mmaxioSky Walking (IOI19_walk)Java
Compilation error
0 ms0 KiB
import java.io.*; import java.util.*; public class walk { static class Point { int x, y; int id; public Point(int x, int y) { this.x = x; this.y = y; } boolean sameAs(Point o) { return x == o.x && y == o.y; } @Override public String toString() { return "(" + x + ", " + y + ")"; } } static class Segment implements Comparable<Segment> { Point p, q; public Segment(Point p, Point q) { this.p = p; this.q = q; } @Override public int compareTo(Segment o) { return Integer.compare(p.x, o.p.x); } @Override public String toString() { if (p.x == q.x) { return String.format("vert at x = %s, y = %s..%s", p.x, p.y, q.y); } else { return String .format("hor at y = %s, x = %s..%s", p.y, p.x, q.x); } } boolean contains(Point pt) { return p.x <= pt.x && pt.x <= q.x && p.y <= pt.y && pt.y <= q.y; } } static class Event implements Comparable<Event> { int y; /** * 0 - horizontal 1 - end of vertical 2 - start of vertical */ int type; Segment seg; public Event(int y, int type, Segment seg) { this.y = y; this.type = type; this.seg = seg; } @Override public int compareTo(Event o) { if (y != o.y) { return y < o.y ? -1 : 1; } return Integer.compare(type, o.type); } } static final int MAX_POINTS = 6_000_000; static final long INF = Long.MAX_VALUE / 5; Point[] lst = new Point[MAX_POINTS]; int lstSz = 0; Point[] horEnds; int horEndsSz = 0; Point[] verEnds; int verEndsSz = 0; Random rng = new Random(); long solve(int[] x1s, int[] y1s, int[] x2s, int[] y2s, int fromX, int toX, int fromY, int toY) { int n = x1s.length; // int n = 20000; Segment[] a = new Segment[n]; int[] allX = new int[2 * n]; horEnds = new Point[2 * n]; verEnds = new Point[2 * n]; Event[] verEvs = new Event[2 * n]; int verEvsSz = 0; Event[] horEvs = new Event[n]; int horEvsSz = 0; for (int i = 0; i < n; i++) { int x1 = x1s[i]; int y1 = y1s[i]; int x2 = x2s[i]; int y2 = y2s[i]; // int x1, y1, x2, y2; // if (i < n / 2) { // x1 = i; // y1 = 0; // x2 = i; // y2 = n / 2 - 1; // } else { // x1 = 0; // y1 = i - n / 2; // x2 = n / 2 - 1; // y2 = i - n / 2; // } // int x1, y1, x2, y2; // if (rng.nextBoolean()) { // x1 = x2 = rng.nextInt(1_000_000_000); // y1 = rng.nextInt(1_000_000_000); // y2 = rng.nextInt(1_000_000_000); // } else { // y1 = y2 = rng.nextInt(1_000_000_000); // x1 = rng.nextInt(1_000_000_000); // x2 = rng.nextInt(1_000_000_000); // } allX[2 * i] = x1; allX[2 * i + 1] = x2; Point p = new Point(x1, y1); Point q = new Point(x2, y2); // System.err.println(p + " - " + q); lst[lstSz++] = p; lst[lstSz++] = q; if (p.x + p.y > q.x + q.y) { Point tmp = p; p = q; q = tmp; } a[i] = new Segment(p, q); if (p.x == q.x) { verEvs[verEvsSz++] = new Event(q.y, 2, a[i]); verEvs[verEvsSz++] = new Event(p.y, 1, a[i]); verEnds[verEndsSz++] = p; verEnds[verEndsSz++] = q; } else { horEvs[horEvsSz++] = new Event(p.y, 0, a[i]); horEnds[horEndsSz++] = p; horEnds[horEndsSz++] = q; } } verEvs = Arrays.copyOf(verEvs, verEvsSz); horEvs = Arrays.copyOf(horEvs, horEvsSz); Arrays.sort(verEvs, new Comparator<Event>() { @Override public int compare(Event o1, Event o2) { return Integer.compare(o1.seg.p.x, o2.seg.p.x); } }); Arrays.sort(horEvs); horEnds = Arrays.copyOf(horEnds, horEndsSz); Arrays.sort(horEnds, byYThenX); verEnds = Arrays.copyOf(verEnds, verEndsSz); Arrays.sort(verEnds, byXThenY); allX = unique(allX); int cntX = allX.length; K = (int) Math.sqrt(cntX); Segment[] hors = new Segment[n]; int horsSz = 0; TreeSet<Segment> vers = new TreeSet<>(); Event[] stripEvs = new Event[2 * n]; int stripEvsSz = 0; int ptrFrom = 0; for (int i = 0; i < cntX; i += K) { // System.err.println(i); int left = allX[i]; int right = allX[Math.min(i + K, cntX - 1)]; horsSz = 0; vers.clear(); while (ptrFrom < verEvsSz && verEvs[ptrFrom].seg.p.x < left) { ptrFrom++; } int ptrStrip = ptrFrom; stripEvsSz = 0; while (ptrStrip < verEvsSz && verEvs[ptrStrip].seg.p.x <= right) { stripEvs[stripEvsSz++] = verEvs[ptrStrip++]; } Arrays.sort(stripEvs, 0, stripEvsSz); int horPtr = 0; int verPtr = 0; while (horPtr < horEvsSz || verPtr < stripEvsSz) { Event curHorEv = horPtr == horEvsSz ? null : horEvs[horPtr]; Event curVerEv = verPtr == stripEvsSz ? null : stripEvs[verPtr]; if (curVerEv == null || (curHorEv != null && curHorEv.y < curVerEv.y)) { Event ev = curHorEv; int xFrom = ev.seg.p.x; int xTo = ev.seg.q.x; if (xTo < left || xFrom > right) { horPtr++; continue; } if (xFrom <= left && xTo >= right) { hors[horsSz++] = ev.seg; } else { flushGrid(hors, horsSz, vers, ev.seg); horsSz = 0; } horPtr++; } else { Event ev = curVerEv; flushGrid(hors, horsSz, vers, null); horsSz = 0; if (ev.type == 1) { vers.add(ev.seg); } else { vers.remove(ev.seg); } verPtr++; } } flushGrid(hors, horsSz, vers, null); } // int fromX = nextInt(); // int fromY = nextInt(); // int toX = nextInt(); // int toY = nextInt(); // int fromX = a[0].p.x; // int fromY = a[0].p.y; // int toX = a[1].q.x; // int toY = a[1].q.y; // int fromX = a[0].p.x; // int fromY = a[0].p.y; // int toX = -1; // int toY = -1; Point source = new Point(fromX, fromY); Point sink = new Point(toX, toY); lst[lstSz++] = source; lst[lstSz++] = sink; for (int i = 0; i < n; i++) { if (a[i].contains(source) || a[i].contains(sink)) { for (int j = 0; j < n; j++) { Point tmp = inter(a[i], a[j]); if (tmp != null) { lst[lstSz++] = tmp; } tmp = inter(a[j], a[i]); if (tmp != null) { lst[lstSz++] = tmp; } } } } System.err.println("scanline " + (System.currentTimeMillis() - startTime) + " ms"); buildGraph(sink); System.err.println("graph built " + (System.currentTimeMillis() - startTime) + " ms"); return shortestPath(source, sink); // System.err.println("shortest path found " // + (System.currentTimeMillis() - startTime) + " ms"); } static Comparator<Point> byXThenY = new Comparator<Point>() { @Override public int compare(Point o1, Point o2) { if (o1.x != o2.x) { return o1.x < o2.x ? -1 : 1; } return Integer.compare(o1.y, o2.y); } }; static Comparator<Point> byYThenX = new Comparator<Point>() { @Override public int compare(Point o1, Point o2) { if (o1.y != o2.y) { return o1.y < o2.y ? -1 : 1; } return Integer.compare(o1.x, o2.x); } }; int[] gHead; int[] gNext; int[] gTo; int[] gLen; int gSz; long[] heur; void buildGraph(Point sink) { Arrays.sort(lst, 0, lstSz, byXThenY); int sz = 1; Point last = lst[0]; for (int i = 1; i < lstSz; i++) { Point ith = lst[i]; if (!ith.sameAs(last)) { lst[sz++] = ith; last = ith; } } // out.println("unique lst " + (System.currentTimeMillis() - startTime) // + " ms"); lst = Arrays.copyOf(lst, sz); heur = new long[sz]; for (int i = 0; i < sz; i++) { lst[i].id = i; heur[i] = manhDist(lst[i], sink); } // System.err.println(Arrays.toString(lst)); // out.println("size = " + sz); // g = new int[sz][8]; // dblDeg = new int[sz * 8]; gHead = new int[sz]; gNext = new int[sz * 4]; gTo = new int[sz * 4]; gLen = new int[sz * 4]; gSz = 0; Arrays.fill(gHead, -1); // System.err.println(verEnds.length + " - verEnds.length"); int ptr = 0; for (int i = 0; i < sz - 1; i++) { while (ptr < verEnds.length && byXThenY.compare(verEnds[ptr], lst[i]) <= 0) { ptr += 2; } if (ptr == 0) { continue; } if (byXThenY.compare(lst[i + 1], verEnds[ptr - 1]) <= 0) { connectNodes(lst[i], lst[i + 1]); } } // out.println("vertical segments " + (System.currentTimeMillis() - // startTime) + " ms"); Arrays.sort(lst, byYThenX); ptr = 0; for (int i = 0; i < sz - 1; i++) { while (ptr < horEnds.length && byYThenX.compare(horEnds[ptr], lst[i]) <= 0) { ptr += 2; } if (ptr == 0) { continue; } if (byYThenX.compare(lst[i + 1], horEnds[ptr - 1]) <= 0) { connectNodes(lst[i], lst[i + 1]); } } // out.println("horizontal segments " + (System.currentTimeMillis() - // startTime) + " ms"); } static class Distance implements Comparable<Distance> { long dist; int v; long key; @Override public int compareTo(Distance o) { return Long.compare(key, o.key); } public Distance(long dist, int v, long key) { this.dist = dist; this.v = v; this.key = key; } } static int manhDist(Point a, Point b) { return Math.abs(a.x - b.x) + Math.abs(a.y - b.y); } long shortestPath(Point source, Point sink) { int n = lst.length; long[] d = new long[n]; Arrays.fill(d, INF); int s = -1; int t = -1; for (int i = 0; i < n; i++) { if (lst[i].sameAs(source)) { s = lst[i].id; } if (lst[i].sameAs(sink)) { t = lst[i].id; } } boolean[] vis = new boolean[n]; int[] que = new int[n]; int head = 0, tail = 0; boolean canReach = false; que[tail++] = s; vis[s] = true; while (head < tail) { int v = que[head++]; if (v == t) { canReach = true; break; } for (int idx = gHead[v]; idx != -1; idx = gNext[idx]) { int u = gTo[idx]; if (!vis[u]) { vis[u] = true; que[tail++] = u; } } } if (!canReach) { return -1; } PriorityQueue<Distance> q = new PriorityQueue<>(); d[s] = 0; q.add(new Distance(0, s, heur[s])); while (!q.isEmpty()) { Distance tmp = q.poll(); long dist = tmp.dist; int v = tmp.v; if (v == t) { return dist; } if (d[v] != dist) { continue; } for (int idx = gHead[v]; idx != -1; idx = gNext[idx]) { int u = gTo[idx]; int len = gLen[idx]; if (d[u] > dist + len) { d[u] = dist + len; q.add(new Distance(d[u], u, d[u] + heur[u])); } } } throw new AssertionError(); } void connectNodes(Point a, Point b) { // System.err.println(a + " " + b); int len = Math.abs(a.x - b.x) + Math.abs(a.y - b.y); int v = a.id; int u = b.id; gTo[gSz] = u; gLen[gSz] = len; gNext[gSz] = gHead[v]; gHead[v] = gSz++; gTo[gSz] = v; gLen[gSz] = len; gNext[gSz] = gHead[u]; gHead[u] = gSz++; } void flushGrid(Segment[] hors, int horsSz, TreeSet<Segment> vers, Segment free) { // System.err.println(hors); // System.err.println(vers); // System.err.println(free); // System.err.println("----------"); if (horsSz != 0 && !vers.isEmpty()) { Segment low = hors[0]; Segment high = hors[horsSz - 1]; Segment left = vers.first(); Segment right = vers.last(); // in these loops we don't check if inter returns null // because they shouldn't and we'll get an exception // while sorting list of points if we'll get null in the list for (int i = 0; i < horsSz; i++) { Segment seg = hors[i]; lst[lstSz++] = inter(seg, left); if (left != right) { lst[lstSz++] = inter(seg, right); } } for (Segment seg : vers) { lst[lstSz++] = inter(low, seg); if (low != high) { lst[lstSz++] = inter(high, seg); } } } if (free == null) { return; } // and here it might not intersect for (Segment seg : vers) { Point tmp = inter(free, seg); if (tmp != null) { lst[lstSz++] = tmp; } } } Point inter(Segment hor, Segment ver) { if (hor.p.y != hor.q.y) { return null; } if (ver.p.x != ver.q.x) { return null; } int resX = ver.p.x; int resY = hor.p.y; if (hor.p.x <= resX && resX <= hor.q.x && ver.p.y <= resY && resY <= ver.q.y) { return new Point(resX, resY); } return null; } // int K = 200; int K; int[] unique(int[] a) { Arrays.sort(a); int sz = 1; for (int i = 1; i < a.length; i++) { if (a[i] != a[sz - 1]) { a[sz++] = a[i]; } } return Arrays.copyOf(a, sz); } walk() { // String input = genAlmostGrid(5000); // System.err.println(input); // br = new BufferedReader(new InputStreamReader(System.in)); // br = new BufferedReader(new StringReader(input)); // out = new PrintWriter(System.out); // solve(); // out.close(); } String genAlmostGrid(int n) { StringBuilder sb = new StringBuilder(); sb.append(n * 4); sb.append('\n'); for (int i = 0; i < n; i++) { int mid = 1 + rng.nextInt(n - 3); sb.append(String.format("%d %d %d %d\n", i, 0, i, mid)); sb.append(String.format("%d %d %d %d\n", i, mid + 1, i, n - 1)); } for (int i = 0; i < n; i++) { int mid = 1 + rng.nextInt(n - 3); sb.append(String.format("%d %d %d %d\n", 0, i, mid, i)); sb.append(String.format("%d %d %d %d\n", mid + 1, i, n - 1, i)); } sb.append(String.format("%d %d %d %d", rng.nextInt(n), rng.nextInt(n), rng.nextInt(n), rng.nextInt(n))); return sb.toString(); } long startTime = System.currentTimeMillis(); public static void main(String[] args) throws IOException { new walk(); } String nextToken() { while (st == null || !st.hasMoreTokens()) { try { st = new StringTokenizer(br.readLine()); } catch (Exception e) { eof = true; return null; } } return st.nextToken(); } String nextString() { try { return br.readLine(); } catch (IOException e) { eof = true; return null; } } int nextInt() throws IOException { return Integer.parseInt(nextToken()); } long nextLong() throws IOException { return Long.parseLong(nextToken()); } double nextDouble() throws IOException { return Double.parseDouble(nextToken()); } long min_distance(int[] x, int[] h, int[] orig_l, int[] orig_r, int[] orig_y, int s, int g) { int n = x.length + orig_l.length; int[] x1s = new int[n]; int[] y1s = new int[n]; int[] x2s = new int[n]; int[] y2s = new int[n]; int ptr = 0; for (int i = 0; i < x.length; i++) { x1s[ptr] = x[i]; y1s[ptr] = 0; x2s[ptr] = x[i]; y2s[ptr] = h[i]; ptr++; } for (int i = 0; i < orig_l.length; i++) { x1s[ptr] = x[orig_l[i]]; y1s[ptr] = orig_y[i]; x2s[ptr] = x[orig_r[i]]; y2s[ptr] = orig_y[i]; ptr++; } int fromX = x[s]; int fromY = 0; int toX = x[g]; int toY = 0; return solve(x1s, y1s, x2s, y2s, fromX, fromY, toX, toY); } }

Compilation message (stderr)

walk.java:689: error: cannot find symbol
		while (st == null || !st.hasMoreTokens()) {
		       ^
  symbol:   variable st
  location: class walk
walk.java:689: error: cannot find symbol
		while (st == null || !st.hasMoreTokens()) {
		                      ^
  symbol:   variable st
  location: class walk
walk.java:691: error: cannot find symbol
				st = new StringTokenizer(br.readLine());
				^
  symbol:   variable st
  location: class walk
walk.java:691: error: cannot find symbol
				st = new StringTokenizer(br.readLine());
				                         ^
  symbol:   variable br
  location: class walk
walk.java:693: error: cannot find symbol
				eof = true;
				^
  symbol:   variable eof
  location: class walk
walk.java:697: error: cannot find symbol
		return st.nextToken();
		       ^
  symbol:   variable st
  location: class walk
walk.java:702: error: cannot find symbol
			return br.readLine();
			       ^
  symbol:   variable br
  location: class walk
walk.java:704: error: cannot find symbol
			eof = true;
			^
  symbol:   variable eof
  location: class walk
8 errors