Submission #143102

#TimeUsernameProblemLanguageResultExecution timeMemory
143102model_codeSky Walking (IOI19_walk)Java
10 / 100
4143 ms240708 KiB
// correct/akm-full.java import java.util.*; class walk { public static final int MAXN = 200 * 1000 + 10; public static final int MAXM = 200 * 1000 + 10; public static final int MAXRM = 5 * MAXM; public static final int MAXV = 2 * 2 * MAXRM; public static final long INF = 1000l * 1000 * 1000 * 1000 * 1000 * 1000; class pair implements Comparable<pair>{ public long a, b; public pair(long a, long b){ this.a = a; this.b = b; } @Override public int compareTo(pair cur){ if(this.a < cur.a)return -1; if(this.a > cur.a)return 1; if(this.b < cur.b)return -1; if(this.b > cur.b)return 1; return 0; } @Override public boolean equals(Object o){ if (o == this) { return true; } if (!(o instanceof pair)) { return false; } pair cur = (pair) o; return (this.a == cur.a && this.b == cur.b); } @Override public int hashCode() { int p = 1000000007; return p * (int)this.a + (int)this.b; } } public long[] dist = new long[MAXV]; public int vcnt = 0; public ArrayList<ArrayList<pair>> edges = new ArrayList<>(); public TreeSet<pair> dij = new TreeSet<>(); public int[] last_x = new int[MAXRM]; public int[] last_vertex = new int[MAXRM]; public int[] last_height = new int[MAXN]; public int[] first_height = new int[MAXN]; public ArrayList<ArrayList<pair>> adds = new ArrayList<>(); public ArrayList<ArrayList<pair>> removes = new ArrayList<>(); public TreeSet<pair> walks = new TreeSet<pair>(); long dijkstra(int start, int dest) { for (int i = 0; i < vcnt; i++) dist[i] = INF; dist[start] = 0; dij.add(new pair(dist[start], start)); while (!dij.isEmpty()) { int v = (int)dij.pollFirst().b; if (v == dest) return dist[v]; for (int i = 0; i < edges.get(v).size(); i++) { int u = (int)edges.get(v).get(i).a; int w = (int)edges.get(v).get(i).b; if (dist[u] > dist[v] + w) { dij.remove(new pair(dist[u], u)); dist[u] = dist[v] + w; dij.add(new pair(dist[u], u)); } } } return -1; } void add_edge(int u, int v, int w) { edges.get(u).add(new pair(v, w)); edges.get(v).add(new pair(u, w)); } int make_vertex(int walk, int x) { if (last_x[walk] == x) return last_vertex[walk]; int cur = vcnt++; edges.add(new ArrayList<>()); if (last_vertex[walk] != -1) add_edge(last_vertex[walk], cur, x - last_x[walk]); last_x[walk] = x; last_vertex[walk] = cur; return cur; } void break_segments(ArrayList<Integer> l, ArrayList<Integer> r, ArrayList<Integer> y, int s, int[] h) { TreeSet<Integer> ts = new TreeSet<Integer>(); for (int i = 0; i < h.length; i++) ts.add(h[i]); List<Integer> heights = new ArrayList<Integer>(); for (Integer x: ts) heights.add(x); for (int i = 0; i < heights.size(); i++) { last_height[i] = -1; first_height[i] = h.length + 1; } for (int i = 0; i < h.length; i++) { int idx = Collections.binarySearch(heights, h[i]); if (i <= s) last_height[idx] = Math.max(last_height[idx], i); if (i >= s) first_height[idx] = Math.min(first_height[idx], i); } for (int i = heights.size() - 2; i >= 0; i--) { last_height[i] = Math.max(last_height[i], last_height[i + 1]); first_height[i] = Math.min(first_height[i], first_height[i + 1]); } for (int i = 0; i < l.size(); i++) if (l.get(i) < s && r.get(i) > s) { int idx = Collections.binarySearch(heights, y.get(i)); if (idx < 0) idx = -(idx + 1); int x = l.get(i); int a = last_height[idx]; int b = first_height[idx]; int q = r.get(i); if (x < a) { r.set(i, a); if (a < b) { l.add(a); r.add(b); y.add(y.get(i)); } } else { r.set(i, b); } if (q > b) { l.add(b); r.add(q); y.add(y.get(i)); } else { } } } long min_distance(int[] x, int[] h, int[] orig_l, int[] orig_r, int[] orig_y, int s, int g) { if (s == g) return 0; int n = x.length; ArrayList<Integer> l = new ArrayList<Integer>(); for (int ttt: orig_l) l.add(ttt); ArrayList<Integer> r = new ArrayList<Integer>(); for (int ttt: orig_r) r.add(ttt); ArrayList<Integer> y = new ArrayList<Integer>(); for (int ttt: orig_y) y.add(ttt); for (int i = 0; i < n; i++) { adds.add(new ArrayList<>()); removes.add(new ArrayList<>()); } break_segments(l, r, y, s, h); break_segments(l, r, y, g, h); int m = l.size(); for (int i = 0; i < m; i++) { last_x[i] = last_vertex[i] = -1; adds.get(l.get(i)).add(new pair(y.get(i), i)); removes.get(r.get(i)).add(new pair(y.get(i), i)); } int sv = -1, gv = -1; long res = 0; walks = new TreeSet<>(); for (int i = 0; i < n; i++) { Collections.sort(adds.get(i)); for (int j = 0; j < adds.get(i).size(); j++) { int v = make_vertex((int)adds.get(i).get(j).b, x[i]); pair it = walks.lower(adds.get(i).get(j)); if (it != null) { int u = make_vertex((int)it.b, x[i]); add_edge(u, v, (int)(adds.get(i).get(j).a - it.a)); } walks.add(adds.get(i).get(j)); } if (i == s) { if (walks.isEmpty() || walks.first().a > h[i]) return -1; sv = make_vertex((int)walks.first().b, x[i]); res += walks.first().a; } if (i == g) { if (walks.isEmpty() || walks.first().a > h[i]) return -1; gv = make_vertex((int)walks.first().b, x[i]); res += walks.first().a; } Collections.sort(removes.get(i)); Collections.reverse(removes.get(i)); for (int j = 0; j < removes.get(i).size(); j++) { int v = make_vertex((int)removes.get(i).get(j).b, x[i]); pair it = walks.lower(removes.get(i).get(j)); if (it != null) { int u = make_vertex((int)it.b, x[i]); add_edge(u, v, (int)(removes.get(i).get(j).a - it.a)); } walks.remove(removes.get(i).get(j)); } } long dij_res = dijkstra(sv, gv); if(dij_res == -1) return -1; return res + dij_res; } }
#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...