Problem:
Score : 200 points

Problem Statement

Kyoto University decided to build a straight wall on the west side of the university to protect against gorillas that attack the university from the west every night.
Since it is difficult to protect the university at some points along the wall where gorillas attack violently, reinforcement materials are also built at those points.
Although the number of the materials is limited, the state-of-the-art technology can make a prediction about the points where gorillas will attack next and the number of gorillas that will attack at each point.
The materials are moved along the wall everyday according to the prediction.
You, a smart student majoring in computer science, are called to find the way to move the materials more efficiently.

Theare are N points where reinforcement materials can be build along the straight wall. They are numbered 1 through N.
Because of the protection against the last attack of gorillas, A_i materials are build at point i (1 \leq i \leq N).
For the next attack, the materials need to be rearranged such that at least B_i materials are built at point i (1 \leq i \leq N).
It costs |i - j| to move 1 material from point i to point j.
Find the minimum total cost required to satisfy the condition by moving materials.
You do not need to consider the attack after the next.

Constraints

1 \leq N \leq 10^5

A_i \geq 1

B_i \geq 1

A_1 + A_2 + ... + A_N \leq 10^{12}

B_1 + B_2 + ... + B_N \leq A_1 + A_2 + ... + A_N

There is at least one way to satisfy the condition.

Input

The input is given from Standard Input in the following format:

N
A_1 A_2 ... A_N
B_1 B_2 ... B_N

Output

Print the minimum total cost required to satisfy the condition.

Partial Scores

30 points will be awarded for passing the test set satisfying the following:

N \leq 100

A_1 + A_2 + ... + A_N \leq 400

Another 30 points will be awarded for passing the test set satisfying the following:

N \leq 10^3

Another 140 points will be awarded for passing the test set without addtional constraints and you can get 200 points in total.

Sample Input 1

2
1 5
3 1

Sample Output 1

2

It costs least to move 2 materials from point 2 to point 1.

Sample Input 2

5
1 2 3 4 5
3 3 1 1 1

Sample Output 2

6

Sample Input 3

27
46 3 4 2 10 2 5 2 6 7 20 13 9 49 3 8 4 3 19 9 3 5 4 13 9 5 7
10 2 5 6 2 6 3 2 2 5 3 11 13 2 2 7 7 3 9 5 13 4 17 2 2 2 4

Sample Output 3

48

The input of this test case satisfies both the first and second additional constraints.

Sample Input 4

18
3878348 423911 8031742 1035156 24256 10344593 19379 3867285 4481365 1475384 1959412 1383457 164869 4633165 6674637 9732852 10459147 2810788
1236501 770807 4003004 131688 1965412 266841 3980782 565060 816313 192940 541896 250801 217586 3806049 1220252 1161079 31168 2008961

Sample Output 4

6302172

The input of this test case satisfies the second additional constraint.

Sample Input 5

2
1 99999999999
1234567891 1

Sample Output 5

1234567890

The input and output values may exceed the range of 32-bit integer.

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Time Limit Exceeded)

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.List;

public class Main {
	static InputStream is;
	static PrintWriter out;
	static String INPUT = "";
	
	public static void solve()
	{
		int n = ni();
		long[] a = new long[n];
		long[] b = new long[n];
		for(int i = 0;i < n;i++){
			a[i] = nl();
		}
		for(int i = 0;i < n;i++){
			b[i] = nl();
		}
		List<Edge> es = new ArrayList<>();
		int src = n, sink = n+1;
		for(int i = 0;i < n;i++){
			es.add(new Edge(src, i, a[i], 0));
			if(i+1 < n)es.add(new Edge(i, i+1, 1000000000005L, 1));
			if(i+1 < n)es.add(new Edge(i+1, i, 1000000000005L, 1));
			es.add(new Edge(i, sink, b[i], 0));
		}
		out.println(solveMinCostFlowWithSPFA(compileWD(sink+1, es), src, sink, 10000000000005L));
	}
	
	public static class Edge
	{
		public int from, to;
		public long capacity;
		public int cost;
		public long flow;
		public Edge complement;
		// public int iniflow;
		
		public Edge(int from, int to, long capacity, int cost) {
			this.from = from;
			this.to = to;
			this.capacity = capacity;
			this.cost = cost;
		}
	}
	
	public static Edge[][] compileWD(int n, List<Edge> edges)
	{
		Edge[][] g = new Edge[n][];
		// cloning
		for(int i = edges.size()-1;i >= 0;i--){
			Edge origin = edges.get(i);
			Edge clone = new Edge(origin.to, origin.from, origin.capacity, -origin.cost);
			clone.flow = origin.capacity;
			clone.complement = origin;
			origin.complement = clone;
			edges.add(clone);
		}
		
		int[] p = new int[n];
		for(Edge e : edges)p[e.from]++;
		for(int i = 0;i < n;i++)g[i] = new Edge[p[i]];
		for(Edge e : edges)g[e.from][--p[e.from]] = e;
		return g;
	}

	// NOT VERIFIED
	public static Edge[][] compileWU(int n, List<Edge> edges)
	{
		Edge[][] g = new Edge[n][];
		// cloning
		for(int i = edges.size()-1;i >= 0;i--){
			Edge origin = edges.get(i);
			Edge back = new Edge(origin.to, origin.from, origin.capacity, origin.cost);
			edges.add(back);
		}
		for(int i = edges.size()-1;i >= 0;i--){
			Edge origin = edges.get(i);
			Edge clone = new Edge(origin.to, origin.from, origin.capacity, -origin.cost);
			clone.flow = origin.capacity;
			clone.complement = origin;
			origin.complement = clone;
			edges.add(clone);
		}
		
		int[] p = new int[n];
		for(Edge e : edges)p[e.from]++;
		for(int i = 0;i < n;i++)g[i] = new Edge[p[i]];
		for(Edge e : edges)g[e.from][--p[e.from]] = e;
		return g;
	}	

	
//	public static long solveMinCostFlow(Edge[][] g, int source, int sink, long all)
//	{
//		int n = g.length;
//		long mincost = 0;
//		int[] potential = new int[n];
//		
//		final int[] d = new int[n];
//		MinHeap q = new MinHeap(n);
//		while(all > 0){
//			// shortest path src->sink
//			Edge[] inedge = new Edge[n];
//			Arrays.fill(d, Integer.MAX_VALUE / 2);
//			d[source] = 0;
//			q.add(source, 0);
//			while(q.size() > 0){
//				int cur = q.argmin();
//				q.remove(cur);
//				for(Edge ne : g[cur]){
//					if(ne.capacity - ne.flow > 0){
//						int nd = d[cur] + ne.cost + potential[cur] - potential[ne.to];
//						if(d[ne.to] > nd){
//							inedge[ne.to] = ne;
//							d[ne.to] = nd;
//							q.update(ne.to, nd);
//						}
//					}
//				}
//			}
//			
//			if(inedge[sink] == null)break;
//			
//			long minflow = all;
//			long sumcost = 0;
//			for(Edge e = inedge[sink];e != null;e = inedge[e.from]){
//				if(e.capacity - e.flow < minflow)minflow = e.capacity - e.flow;
//				sumcost += e.cost;
//			}
//			mincost += minflow * sumcost;
//			for(Edge e = inedge[sink];e != null;e = inedge[e.from]){
//				e.flow += minflow;
//				e.complement.flow -= minflow;
//			}
//			
//			all -= minflow;
//			for(int i = 0;i < n;i++){
//				potential[i] += d[i];
//			}
//		}
//		return mincost;
//	}
	
	public static class DQ {
		public int[] q;
		public int n;
		protected int pt, ph;
		
		public DQ(int n){ this.n = Integer.highestOneBit(n)<<1; q = new int[this.n]; pt = ph = 0; }
		
		public void addLast(int x){ q[ph] = x; ph = ph+1&n-1; }
		public void addFirst(int x){ pt = pt+n-1&n-1; q[pt] = x; }
		public int pollFirst(){ int ret = q[pt]; pt = pt+1&n-1; return ret; }
		public int pollLast(){ ph = ph+n-1&n-1; int ret = q[ph]; return ret; }
		public int getFirst(){ return q[pt]; }
		public int getFirst(int k){ return q[pt+k&n-1]; }
		public int getLast(){ return q[ph+n-1&n-1]; }
		public int getLast(int k){ return q[ph+n-k-1&n-1]; }
		public void clear(){ pt = ph = 0; }
		public int size(){ return ph-pt+n&n-1; }
		public boolean isEmpty(){ return ph==pt; }
	}

	
	public static long solveMinCostFlowWithSPFA(Edge[][] g, int source, int sink, long all)
	{
		int n = g.length;
		long mincost = 0;
		
		final int[] d = new int[n];
		DQ q = new DQ(n);
		boolean[] inq = new boolean[n];
		while(all > 0){
			// shortest path src->sink
			Edge[] inedge = new Edge[n];
			Arrays.fill(d, Integer.MAX_VALUE / 2);
			d[source] = 0;
			q.addLast(source);
			while(!q.isEmpty()){
				int cur = q.pollFirst();
				inq[cur] = false;
				for(Edge ne : g[cur]){
					if(ne.capacity - ne.flow > 0){
						int nd = d[cur] + ne.cost;
						if(d[ne.to] > nd){
							inedge[ne.to] = ne;
							d[ne.to] = nd;
							if(!inq[ne.to]){
								q.addLast(ne.to);
								inq[ne.to] = true;
							}
						}
					}
				}
			}
			
			if(inedge[sink] == null)break;
			
			long minflow = all;
			long sumcost = 0;
			for(Edge e = inedge[sink];e != null;e = inedge[e.from]){
				if(e.capacity - e.flow < minflow)minflow = e.capacity - e.flow;
				sumcost += e.cost;
			}
			mincost += minflow * sumcost;
			for(Edge e = inedge[sink];e != null;e = inedge[e.from]){
				e.flow += minflow;
				e.complement.flow -= minflow;
			}
			
			all -= minflow;
		}
		return mincost;
	}
	
	public static void main(String[] args) throws Exception
	{
//		int n = 100000, m = 99999;
//		Random gen = new Random();
//		StringBuilder sb = new StringBuilder();
//		sb.append(n + " ");
//		for (int i = 0; i < n; i++) {
//			sb.append(gen.nextInt(20000000)+1 + " ");
//		}
//		for (int i = 0; i < n; i++) {
//			sb.append(gen.nextInt(10000000)+1 + " ");
//		}
//		INPUT = sb.toString();

		long S = System.currentTimeMillis();
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);
		
		solve();
		out.flush();
		long G = System.currentTimeMillis();
		tr(G-S+"ms");
	}
	
	private static boolean eof()
	{
		if(lenbuf == -1)return true;
		int lptr = ptrbuf;
		while(lptr < lenbuf)if(!isSpaceChar(inbuf[lptr++]))return false;
		
		try {
			is.mark(1000);
			while(true){
				int b = is.read();
				if(b == -1){
					is.reset();
					return true;
				}else if(!isSpaceChar(b)){
					is.reset();
					return false;
				}
			}
		} catch (IOException e) {
			return true;
		}
	}
	
	private static byte[] inbuf = new byte[1024];
	static int lenbuf = 0, ptrbuf = 0;
	
	private static int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}
	
	private static boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
//	private static boolean isSpaceChar(int c) { return !(c >= 32 && c <= 126); }
	private static int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }
	
	private static double nd() { return Double.parseDouble(ns()); }
	private static char nc() { return (char)skip(); }
	
	private static String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}
	
	private static char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}
	
	private static char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}
	
	private static int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}
	
	private static int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}
		
		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}
	
	private static long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}
		
		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}
	
	private static void tr(Object... o) { if(INPUT.length() != 0)System.out.println(Arrays.deepToString(o)); }
}