Submission #735096

#TimeUsernameProblemLanguageResultExecution timeMemory
735096SchoolAccountSplit the sequence (APIO14_sequence)Java
Compilation error
0 ms0 KiB
import java.io.*; import java.math.BigInteger; import java.util.*; public class Main { // change to ur file private static final String localTestInputFile = "C:\\Users\\anaba\\eclipse-workspace\\test\\src\\main\\java\\input.in"; private static final String localTestOutputFile = "C:\\Users\\anaba\\eclipse-workspace\\test\\src\\main\\java\\input.out"; // for usaco only private static final String name = "cowjog"; // constants to use private static final int mod = 1_000_000_007, mm = 998244353, inf = Integer.MAX_VALUE; private static final int[][] d4 = new int[][] {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; private static final long inf2 = Long.MAX_VALUE; // all are primes private static final long mod1 = 4611686018427387847L, mod2 = 4611686018427387833L, mod3 = 4611686018427387813L; // need to generate Mod.fast(int max) first to use private static long[] fact; private static PrintWriter out; private static FastIO sc; private static long time = -1; public static void main(String[] args) throws Exception { // super giga brain reader that accounts for all platforms and displays time when its ur own platform try { if(name.length() != 0 && new File(name+".in").exists()) { sc = new FastIO(name+".in"); out = new PrintWriter(name+".out"); }else if(new File(localTestInputFile).exists()){ sc = new FastIO(localTestInputFile); out = new PrintWriter(new BufferedOutputStream(System.out)); time = System.currentTimeMillis(); }else { sc = new FastIO(System.in); out = new PrintWriter(new BufferedOutputStream(System.out)); } }catch(SecurityException e) { sc = new FastIO(System.in); out = new PrintWriter(new BufferedOutputStream(System.out)); } // for(int T = sc.nextInt(); T>0; T--) solve(); if(time != -1) System.out.println("Time: "+(System.currentTimeMillis()-time)+"ms"); out.close(); } private static void solve() throws Exception { int N = sc.nextInt(), K = sc.nextInt()+1; long[] nums = sc.longArr(N); for(int i = 1; i<N; i++) nums[i]+=nums[i-1]; long[][] dp = new long[N][K]; int[][] best = new int[N][K]; CHT<Integer>[] max = new CHT[K]; for(int i = 0; i<K; i++) max[i] = new CHT(true); max[0].add(0, 0, -1); for(int i = 0; i<N; i++){ for(int j = 0; j<K; j++){ Two<Long, Integer> get = max[j].get(nums[i]); dp[i][j] = get.a; best[i][j] = get.b; if(j != K-1) max[j+1].add(nums[i], dp[i][j]-nums[i]*nums[i], i); } } out.println(dp[N-1][K-1]); int[] order = new int[K-1]; int c = best[N-1][K-1]; for(int i = 0; i<K-1; i++){ order[K-i-2] = c+1; c = best[c][K-i-2]; } out(order); } // Mo's algorithm private static class MoAlg<T, Edit> { public interface Add<Edit, T> {public void add(Edit a, T curr, boolean first);} public interface Rem<Edit, T> {public void rem(Edit a, T curr, boolean first);} public interface Get<Edit> {public Object get(Edit a);} private final T[] nums; private final int block; private final List<int[]> quer; private final Add<Edit, T> add; private final Rem<Edit, T> rem; private final Get<Edit> get; private Edit def; public MoAlg(T[] nums, Add<Edit, T> add, Rem<Edit, T> rem, Get<Edit> get, Edit def) { this.add = add; this.rem = rem; this.get = get; this.nums = nums; this.def = def; block = (int)Math.sqrt(nums.length); quer = new ArrayList<>(); } public void add(int l, int r) { quer.add(new int[] {l, r, quer.size()}); } public Object[] getAns() { Collections.sort(quer, (a, b) -> a[0]/block == b[0]/block ? ((((a[0]/block)&1) == 0) ? a[1]-b[1]:b[1]-a[1]):a[0]-b[0]); int l = 0, r = -1; Object[] ans = new Object[quer.size()]; for(int[] a: quer) { if(r < a[0] || l > a[1]) { for(int i = l; i<=r; i++) rem.rem(def, nums[i], true); for(int i = a[0]; i<=a[1]; i++) add.add(def, nums[i], false); }else { if(l > a[0]) for(int i = l-1; i>=a[0]; i--) add.add(def, nums[i], true); else for(int i = l; i<a[0]; i++) rem.rem(def, nums[i], true); if(r > a[1]) for(int i = r; i>a[1]; i--) rem.rem(def, nums[i], false); else for(int i = r+1; i<=a[1]; i++) add.add(def, nums[i], false); } l = a[0]; r = a[1]; ans[a[2]] = get.get(def); } return ans; } } // combiners used for later public interface Comb<Val>{Val oper(Val left, Val right);} public interface Prop<Val, Lz> {Val oper(Lz top, Val current, long len);} public interface LZ<Lz>{Lz oper(Lz top, Lz current);} public interface Def<Val>{Val get(long len);} public interface DefLz<Lz>{Lz get();} // convex hull trick private static class CHT<T> { private List<Line<T>> lines; private boolean max; public CHT(boolean max) { this.lines = new ArrayList<>(); this.max = max; } public boolean isEmpty() {return lines.isEmpty();} public void add(long m, long b) {add(m, b, null);} public void add(long m, long b, T curr) { if(max) { m*=-1; b*=-1; } Line line = new Line(m, b, curr); while (lines.size() >= 2) { Line l1 = lines.get(lines.size() - 1); Line l2 = lines.get(lines.size() - 2); if (BigInteger.valueOf(l1.b-l2.b).multiply(BigInteger.valueOf(l1.m-line.m)) .compareTo(BigInteger.valueOf(line.b-l1.b).multiply(BigInteger.valueOf(l2.m-l1.m))) == 1) lines.remove(lines.size() - 1); else break; } lines.add(line); } public Two<Long, T> get(long x) { int lo = 0, hi = lines.size() - 1; while (lo < hi) { int mid = (lo + hi) / 2; if (lines.get(mid).yValue(x) < lines.get(mid + 1).yValue(x)) hi = mid; else lo = mid + 1; } return new Two<>((max ? -1:1)*lines.get(lo).yValue(x), lines.get(lo).get()); } private static class Line<T> { private long m; private long b; private T curr; public Line(long m, long b, T curr) { this.m = m; this.b = b; this.curr = curr; } public T get(){ return curr; } public long yValue(long x) { return m * x + b; } } } // convex hull private static int[][] hull(int[][] points) { Arrays.sort(points, (o1, o2) -> o1[0] != o2[0] ? o1[0] - o2[0] : o1[1] - o2[1]); int n = points.length; boolean[] used = new boolean[n]; int[] hull = new int[n + 2]; int top = 0; for (int i = 0; i < n; i++) { while (top >= 2 && area(points[hull[top - 1]], points[hull[top]], points[i]) > 0) { used[hull[top--]] = false; } hull[++top] = i; used[i] = true; } used[0] = false; for (int i = n - 1; i >= 0; i--) { if (used[i]) continue; while (top >= 2 && area(points[hull[top - 1]], points[hull[top]], points[i]) > 0) { top--; } hull[++top] = i; } top--; int[][] res = new int[top][2]; for (int i = 1; i <= top; i++) res[i - 1] = points[hull[i]]; return res; }private static int area(int[] a, int[] b, int[] c) { return cross(b[0] - a[0], b[1] - a[1], c[0] - a[0], c[1] - a[1]); }private static int cross(int x1, int y1, int x2, int y2) { return x1 * y2 - x2 * y1; } // dijkstra's private static long[] minPath(int x, List<int[]>[] g) { long[] l = new long[g.length]; PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> Long.compare(l[a], l[b])); Arrays.fill(l, Long.MAX_VALUE); l[x] = 0; pq.add(x); while (!pq.isEmpty()) { int c = pq.poll(); for (int[] a : g[c]) if (l[a[0]] > l[c] + a[1]) { l[a[0]] = l[c] + a[1]; pq.add(a[0]); } } return l; } // range add, point query private static class RevBIT { private final long[] bit; private final long[] arr; private final int len; public RevBIT(int len) { bit = new long[len + 1]; arr = new long[len]; this.len = len; } public void set(int ind, long val) { add(ind, ind, val - get(ind)); } public void add(int s, int e, long val) { add(s, val); if (e != len - 1) add(e + 1, -val); } private void add(int ind, long val) { arr[ind] += val; ind++; for (; ind <= len; ind += ind & -ind) bit[ind] += val; } public long diff(int ind) { return arr[ind]; } public long get(int ind) { ind++; long sum = 0; for (; ind > 0; ind -= ind & -ind) sum += bit[ind]; return sum; } @Override public String toString() { StringBuilder ret = new StringBuilder(); ret.append("["); for (int i = 0; i < len; i++) ret.append(get(i) + (i == len - 1 ? "]" : ", ")); return ret.toString(); } } // binary jumping lca private static int lca(int a, int b, int[][] jp, int[] depth) { if(depth[a] > depth[b]) { int s = a; a = b; b = s; } b = jump(b, depth[b]-depth[a], jp); if(a == b) return a; for(int i = jp[0].length-1; i>=0; i--) if(jp[a][i] != jp[b][i]) { a = jp[a][i]; b = jp[b][i]; } return jp[a][0]; } // binary jumping jump private static int jump(int a, int k, int[][] jp) { for(int i = 0; i<jp[0].length; i++) if((k&(1<<i)) != 0) { a = jp[a][i]; if(a == -1) return -1; } return a; } // heavy light decomposition private static int[][] HLD(List<Integer>[] g){ int N = g.length; int[] pos = new int[N], last = new int[N], cnt = new int[N]; dfsCNTHLD(g, cnt, 0, -1); dfsHLD(g, pos, last, 0, 0, -1, cnt); return new int[][] {pos, last}; }private static void dfsCNTHLD(List<Integer>[] g, int[] cnt, int s, int p) { cnt[s] = 1; for(int i: g[s]) if(i != p) { dfsCNTHLD(g, cnt, i, s); cnt[s]+=cnt[i]; } }private static int dfsHLD(List<Integer>[] g, int[] pos, int[] last, int timer, int s, int p, int[] cnt) { pos[s] = timer++; int m = -1; for(int i: g[s]) if(i != p) if(m == -1 || cnt[i] > cnt[m]) m = i; if(m == -1) return timer; last[m] = last[s]; timer = dfsHLD(g, pos, last, timer, m, s, cnt); for(int i: g[s]) if(i != p && i != m) { last[i] = i; timer = dfsHLD(g, pos, last, timer, i, s, cnt); } return timer; } // strongly connected components private static List<List<Integer>> SCC(List<Integer>[] g) { int N = g.length; int[] disc = new int[N]; int[] low = new int[N]; Arrays.fill(disc, -1); Arrays.fill(low, -1); boolean stackMember[] = new boolean[N]; LinkedList<Integer> st = new LinkedList<>(); LinkedList<List<Integer>> ans = new LinkedList<>(); ans.add(new LinkedList<>()); for (int i = 0; i<N; i++) if (disc[i] == -1) SCCUtil(i, low, disc, stackMember, st, 0, g, ans); ans.pollLast(); return ans; }private static int SCCUtil(int s, int[] low, int[] disc, boolean[] stackMember, LinkedList<Integer> st, int time, List<Integer>[] g, List<List<Integer>> ans) { disc[s] = time; low[s] = time; time++; stackMember[s] = true; st.push(s); for(int i: g[s]){ if (disc[i] == -1) { time = SCCUtil(i, low, disc, stackMember, st, time, g, ans); low[s] = min(low[s], low[i]); } else if(stackMember[i] == true) low[s] = min(low[s], disc[i]); } int w = -1; if (low[s] == disc[s]) { while (w != s) { w = st.pop(); ans.get(ans.size()-1).add(w); stackMember[w] = false; } ans.add(new LinkedList<>()); } return time; } // depth of tree in arr[0], par of nodes in arr[1] private static int[][] depthPar(int s, List<Integer>[] g) { int[][] ans = new int[2][g.length]; depthParDFS(g, s, -1, ans); return ans; }private static void depthParDFS(List<Integer>[] g, int s, int p, int[][] d) { d[1][s] = p; for(int i: g[s]) if(i != p) { d[0][i] = d[0][s]+1; depthParDFS(g, i, s, d); } } // compresses nodes with 1 child // new tree in arr[0], list of previous nodes that compress to new nodes in arr[1] private static List<Integer>[][] treeComp(List<Integer>[] g){ int N = g.length; if(N == 1) { List<Integer>[][] ans = new List[2][1]; ans[0][0] = new LinkedList<>(); ans[1][0] = new LinkedList<>(); ans[1][0].add(0); return ans; } int[] map = new int[N]; int K = treeCompGetCount(g, 0, -1, map, 0); List<Integer>[][] ans = new List[2][K]; for(int i = 0; i<K; i++) { ans[0][i] = new LinkedList<>(); ans[1][i] = new LinkedList<>(); } treeCompDFS(g, map, ans, 0); return ans; }private static int treeCompGetCount(List<Integer>[] g, int s, int p, int[] map, int time) { g[s].remove((Integer)p); if(p == -1 || g[p].size() != 1) map[s] = time++; else map[s] = -1; for(int i: g[s]) if(i != p) time = treeCompGetCount(g, i, s, map, time); return time; }private static void treeCompDFS(List<Integer>[] g, int[] map, List<Integer>[][] ret, int s) { int curr = s; while(g[curr].size() == 1) { ret[1][map[s]].add(curr); curr = g[curr].get(0); } ret[1][map[s]].add(curr); for(int i: g[curr]) { ret[0][map[s]].add(map[i]); treeCompDFS(g, map, ret, i); } } // detects cycle private static boolean hasCycle(List<Integer>[] g) { byte[] vis = new byte[g.length]; for(int i = 0; i<g.length; i++) if(vis[i] == 0 && hasCycleHelper(g, i, vis)) return true; return false; }private static boolean hasCycleHelper(List<Integer>[] g, int s, byte[] vis) { vis[s] = 1; for(int i: g[s]) if(vis[i] == 1) return true; else if(vis[i] == 0 && hasCycleHelper(g, i, vis)) return true; vis[s] = 2; return false; } // counts amount of numbers using treemap private static class Cnt<T> { public TreeMap<T, Long> map; boolean first = true; public Cnt() {} public long get(T num) { if(first) { if(num instanceof Long) map = new TreeMap<>((a, b) -> Long.compare((long)a, (long)b)); else map = new TreeMap<>(); first = false; } Long get = map.get(num); if (get == null) return 0; return get; } public void add(T num) { add(num, 1); } public void rem(T num) { add(num, -1); } public void rem(T num, long cnt) { add(num, -cnt); } public void add(T num, long cnt) { if(first) { if(num instanceof Long) map = new TreeMap<>((a, b) -> Long.compare((long)a, (long)b)); else map = new TreeMap<>(); first = false; } Long get = map.get(num); if (get == null) get = 0L; get += cnt; if (get == 0) map.remove(num); else map.put(num, get); } public boolean isEmpty() { if(map == null) return true; return map.isEmpty(); } public T min() { if(map == null) return null; return map.isEmpty() ? null:map.firstKey(); } public T max() { if(map == null) return null; return map.isEmpty() ? null:map.lastKey(); } @Override public String toString() { return map.toString(); } } // 1 line convenience functions private static void print(int... a) { System.out.println(a.length == 0 ? "":Arrays.toString(a).replaceAll("2147483647", "inf")); } private static void print(long... a) { System.out.println(a.length == 0 ? "":Arrays.toString(a).replaceAll("2147483647", "inf")); } private static void out(int[] a) { for(int i: a) out.print(i+" "); out.println(); } private static void out(long[] a) { for(long l: a) out.print(l+" "); out.println(); } private static void outLn(int[] a) { for(int i: a) out.println(i); } private static void outLn(long[] a) { for(long l: a) out.println(l); } // basic math private static int gcd(int a, int b) { while(b > 0) { int t = a%b; a = b; b = t; } return a; } private static int max(int... x) { for (int i = 1; i < x.length; i++) x[0] = Math.max(x[0], x[i]); return x[0]; } private static int min(int... x) { for (int i = 1; i < x.length; i++) x[0] = Math.min(x[0], x[i]); return x[0]; } private static long max(long... x) { for (int i = 1; i < x.length; i++) x[0] = Math.max(x[0], x[i]); return x[0]; } private static long min(long... x) { for (int i = 1; i < x.length; i++) x[0] = Math.min(x[0], x[i]); return x[0]; } // modular arithmatic private static class Mod { private Mod() { } public static void fact(int max) { fact = new long[max+1]; fact[0] = 1; for(int i = 1; i<=max; i++) fact[i] = (fact[i-1]*i)%mod; } public static long nCk(int n, int k) { return (fact[n]*((inv(fact[k])*inv(fact[n-k])%mod)))%mod; } public static long mul(long a, long b, long mod) { long ret = 0; while(b > 0) { if((b&1) == 1) ret = (ret+a)%mod; a = (a<<1)%mod; b>>=1; } return ret; } public static long inv(long x) { return pow(x, mod - 2, mod); } public static long inv(long x, long mod) { return pow(x, mod - 2, mod); } public static long pow(long x, long n) { return pow(x, n, mod); } public static long pow(long x, long n, long mod) { x %= mod; long res = 1; while (n > 0) { if ((n & 1) == 1) res = res * x % mod; x = x * x % mod; n >>= 1; } return res; } } // binary search (last true, first true) private static class BS { public interface Oper { boolean test(long num); } private BS() { } public static long last(long lo, long hi, Oper oper) { lo--; while (lo < hi) { long mid = lo + (hi - lo + 1) / 2; if (oper.test(mid)) { lo = mid; } else { hi = mid - 1; } } return lo; } public static long first(long lo, long hi, Oper oper) { hi++; while (lo < hi) { long mid = lo + (hi - lo) / 2; if (oper.test(mid)) { hi = mid; } else { lo = mid + 1; } } return lo; } } // linked lists that can merge in O(1) private static class Merge<T> implements Iterable<T> { private class Node { public T num; public Node next = null; public Node(T num) { this.num = num; } } private class mergeIterator implements Iterator<T> { private Node s; public mergeIterator(Node s) { this.s = s; } @Override public boolean hasNext() { return s != null; } @Override public T next() { T ret = s.num; s = s.next; return ret; } } private Node s, e; private int size; public Merge() { s = e = null; size = 0; } public void addF(T n) { if (s == null) s = e = new Node(n); else { Node p = new Node(n); p.next = s; s = p; } size++; } public void add(T n) { if (s == null) s = e = new Node(n); else { e.next = new Node(n); e = e.next; } size++; } public void addAll(Merge<T> m) { if (m == this) return; if (e == null) s = e = m.s; else e.next = m.s; e = m.e; size += m.size; } public int size() { return size; } public String toString() { StringBuilder sb = new StringBuilder(); sb.append("["); for (T i : this) sb.append(i + ", "); if (sb.length() > 1) sb.delete(sb.length() - 2, sb.length()); sb.append("]"); return sb.toString(); } @Override public Iterator<T> iterator() { return new mergeIterator(s); } public void clear() { s = e = null; size = 0; } } //DSU but can store memory in each component private static class DSU<Val> { private Val[] vals; private int[] par, size; private Merge<Integer>[] all; private int cc; private Comb<Val> o; public DSU(int N, boolean storeAll) {this(N, null, storeAll);} public DSU(int N, Comb<Val> o, Def<Val[]> def) {this(N, o, false);} public DSU(int N) {this(N, null, false);} public DSU(int N, Comb<Val> o, boolean storeAll) { par = new int[N]; size = new int[N]; cc = N; Arrays.fill(par, -1); Arrays.fill(size, 1); this.o = o; if(o != null) vals = (Val[]) new Object[N]; if(storeAll) { all = new Merge[N]; for(int i = 0; i<N; i++) { all[i] = new Merge(); all[i].add(i); } } } public Val getVal(int num) { return vals[get(num)]; } public int size(int num) { return size[get(num)]; } public int get(int num) { return par[num] == -1 ? num : (par[num] = get(par[num])); } public boolean isSame(int x, int y) { return get(x) == get(y); } public boolean unite(int x, int y) { int p1 = get(x), p2 = get(y); if (p1 == p2) return false; Val next = o == null ? null:o.oper(vals[p1], vals[p2]); Merge<Integer> a = all == null ? null:all[p1], b = all == null ? null:all[p2]; if (size[p1] < size[p2]) { int s = p2; p2 = p1; p1 = s; Merge<Integer> v = a; a = b; b = v; } size[p1] += size[p2]; par[p2] = p1; cc--; if(vals != null) vals[p1] = next; if(a != null) a.addAll(b); return true; } public int getCC() { return cc; } public void set(int num, Val curr) { vals[get(num)] = curr; } public Merge<Integer> getAll(int num) { return all[get(num)]; } } // pairs 2 objects into 1 (can be used in hashmap) private static class Two<A, B> { public A a; public B b; public Two(A a, B b) { this.a = a; this.b = b; } @Override public boolean equals(Object obj) { if (!(obj instanceof Two)) return false; Two curr = (Two) obj; return curr.a.equals(a) && curr.b.equals(b); } @Override public int hashCode() { long seed = a.hashCode(); seed = seed << 32; seed |= b.hashCode(); Random r = new Random(); r.setSeed(seed); return r.nextInt(); } @Override public String toString() { return "(" + a.toString() + ", " + b.toString() + ")"; } } // FastIO reader private static class FastIO { InputStream dis; byte[] buffer = new byte[500007]; int pointer = 0, end = 0; public FastIO(String fileName) throws Exception { dis = new FileInputStream(fileName); } public char nextChar() throws Exception { return next().charAt(0); } public FastIO(InputStream is) throws Exception { dis = is; } public int nextInt() throws Exception { int ret = 0; byte b; do { b = nextByte(); } while (b <= ' '); boolean negative = false; if (b == '-') { negative = true; b = nextByte(); } while (b >= '0' && b <= '9') { ret = 10 * ret + b - '0'; b = nextByte(); } return (negative) ? -ret : ret; } public long nextLong() throws Exception { long ret = 0; byte b; do { b = nextByte(); } while (b <= ' '); boolean negative = false; if (b == '-') { negative = true; b = nextByte(); } while (b >= '0' && b <= '9') { ret = 10 * ret + b - '0'; b = nextByte(); } return (negative) ? -ret : ret; } private byte nextByte() throws Exception { while (pointer >= end) { end = dis.read(buffer, 0, buffer.length); pointer = 0; } return buffer[pointer++]; } public double nextDouble() throws Exception { return Double.parseDouble(next()); } public String next() throws Exception { StringBuffer ret = new StringBuffer(); byte b; do { b = nextByte(); } while (b <= ' '); while (b > ' ') { ret.appendCodePoint(b); b = nextByte(); } return ret.toString(); } public long[] longArr(int len) throws Exception{ long[] ans = new long[len]; for (int i = 0; i < len; i++) ans[i] = nextLong(); return ans; } public int[] nextArr() throws Exception { return nextArr(nextInt()); } public int[] nextArr(int len) throws Exception { int[] ans = new int[len]; for (int i = 0; i < len; i++) ans[i] = nextInt(); return ans; } public List<Integer>[] nextTree() throws Exception { return nextTree(nextInt()); } public LinkedList<Integer>[] nextTree(int n) throws Exception { return nextGraph(n, n - 1); } public LinkedList<int[]>[] weightGraph(int n, int m) throws Exception{ return weightGraph(n, m, false); } public LinkedList<int[]>[] weightGraph(int n, int m, boolean directed) throws Exception { LinkedList<int[]>[] ans = new LinkedList[n]; for(int i = 0; i<n; i++) ans[i] = new LinkedList<>(); for(int i = 0; i<m; i++) { int a = nextInt()-1, b = nextInt()-1, w = nextInt(); ans[a].add(new int[] {b, w}); if(!directed) ans[b].add(new int[] {a, w}); } return ans; } public LinkedList<Integer>[] nextGraph(int n, int m) throws Exception { return nextGraph(n, m, false); } public LinkedList<Integer>[] nextGraph(int n, int m, boolean directed) throws Exception { LinkedList<Integer>[] ans = new LinkedList[n]; for (int i = 0; i < n; i++) ans[i] = new LinkedList<>(); for (int i = 0; i < m; i++) { int a = nextInt() - 1, b = nextInt() - 1; ans[a].add(b); if(!directed) ans[b].add(a); } return ans; } public char[] chars() throws Exception { return next().toCharArray(); } } }

Compilation message (stderr)

sequence.java:5: error: class Main is public, should be declared in a file named Main.java
public class Main {
       ^
Note: sequence.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error