Problem:
Score : 1000 points

Problem Statement

You are given a sequence a = \{a_1, ..., a_N\} with all zeros, and a sequence b = \{b_1, ..., b_N\} consisting of 0 and 1. The length of both is N.

You can perform Q kinds of operations. The i-th operation is as follows:

Replace each of a_{l_i}, a_{l_i + 1}, ..., a_{r_i} with 1.

Minimize the hamming distance between a and b, that is, the number of i such that a_i \neq b_i, by performing some of the Q operations.

Constraints

1 \leq N \leq 200,000

b consists of 0 and 1.

1 \leq Q \leq 200,000

1 \leq l_i \leq r_i \leq N

If i \neq j, either l_i \neq l_j or r_i \neq r_j.

Input

Input is given from Standard Input in the following format:

N
b_1 b_2 ... b_N
Q
l_1 r_1
l_2 r_2
:
l_Q r_Q

Output

Print the minimum possible hamming distance.

Sample Input 1

3
1 0 1
1
1 3

Sample Output 1

1

If you choose to perform the operation, a will become \{1, 1, 1\}, for a hamming distance of 1.

Sample Input 2

3
1 0 1
2
1 1
3 3

Sample Output 2

0

If both operations are performed, a will become \{1, 0, 1\}, for a hamming distance of 0.

Sample Input 3

3
1 0 1
2
1 1
2 3

Sample Output 3

1

Sample Input 4

5
0 1 0 1 0
1
1 5

Sample Output 4

2

It may be optimal to perform no operation.

Sample Input 5

9
0 1 0 1 1 1 0 1 0
3
1 4
5 8
6 7

Sample Output 5

3

Sample Input 6

15
1 1 0 0 0 0 0 0 1 0 1 1 1 0 0
9
4 10
13 14
1 7
4 14
9 11
2 6
7 8
3 12
7 13

Sample Output 6

5

Sample Input 7

10
0 0 0 1 0 0 1 1 1 0
7
1 4
2 5
1 3
6 7
9 9
1 5
7 9

Sample Output 7

1

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Accepted)

import java.util.*;
import java.io.*;

public class Main {
	
	void solve() {
		int n=  in.nextInt();
		int[] zeros = new int[n + 1];
		int[] ones = new int[n + 1];
		for (int i = 1; i <= n; i++) {
			int x = in.nextInt();
			zeros[i] = zeros[i - 1];
			ones[i] = ones[i - 1];
			if (x == 0) {
				zeros[i]++;
			} else {
				ones[i]++;
			}
		}
		
		int q = in.nextInt();
		List<Query>[] left = new List[n + 1], right = new List[n + 1];
		for (int i = 0; i <= n; i++) {
			left[i] = new ArrayList<>();
			right[i] = new ArrayList<>();
		}
		Query[] qs = new Query[q];
		for (int i = 0; i < q; i++) {
			qs[i] = new Query(in.nextInt(), in.nextInt(), i);
			left[qs[i].l].add(qs[i]);
			right[qs[i].r].add(qs[i]);
		}
		
		int[] ans = new int[q];

		SegmentTree treeZ = new SegmentTree(n + 1);
		SegmentTree treeO = new SegmentTree(n + 1);
		
		int result = ones[n];
		for (int l = 1; l <= n; l++) {
			
			for (Query query : left[l]) {
				ans[query.i] = zeros[query.r] - zeros[query.l - 1] + ones[query.l - 1];
				
				ans[query.i] = Math.min(ans[query.i], treeZ.get(query.l, query.r) + zeros[query.r]);
				
				ans[query.i] = Math.min(ans[query.i], treeO.get(0, query.l) + zeros[query.r] - zeros[query.l - 1] + ones[query.l - 1]);
				
				result = Math.min(result, ans[query.i] + ones[n] - ones[query.r]);
			}
			
			for (Query query : left[l]) {
				treeZ.set(query.r, ans[query.i] - zeros[query.r]);
				treeO.set(query.r, ans[query.i] - ones[query.r]);
			}
		}
		out.println(result);
	}
	
	int INF = Integer.MAX_VALUE / 3;
	
	class SegmentTree {
		int[] min;
		int size;
		public SegmentTree(int n) {
			min = new int[4 * n];
			size = n;
			Arrays.fill(min, INF);
		}
		
		void set(int pos, int val) {
			set(0, size, pos, val, 0);
		}
		
		void set(int l, int r, int pos, int val, int i) {
			if (l + 1 == r) {
				min[i] = Math.min(min[i], val);
				return;
			}
			int m = (l + r) >>> 1;
			if (pos < m) {
				set(l, m, pos, val, 2 * i + 1);
			} else {
				set(m, r, pos, val, 2 * i + 2);
			}
			min[i] = Math.min(min[2 * i + 1], min[2 * i + 2]);
		}
		
		int get(int left, int right) {
			return get(0, size, left, right, 0);
		}
		
		int get(int l, int r, int left, int right, int i) {
			if (left <= l && r <= right) {
				return min[i];
			} else if (right <= l || r <= left) {
				return INF;
			} else {
				int m = (l + r) >>> 1;
				return Math.min(get(l, m, left, right, 2 * i + 1), get(m, r, left, right, 2 * i + 2));
			}
		}
	}
	
	class Query {
		int l, r, i;

		public Query(int l, int r, int i) {
			super();
			this.l = l;
			this.r = r;
			this.i = i;
		}

		@Override
		public String toString() {
			return "Query [l=" + l + ", r=" + r + ", i=" + i + "]";
		}
		
		
	}

	FastScanner in;
	PrintWriter out;

	void run() {
		in = new FastScanner();
		out = new PrintWriter(System.out);
		solve();
		out.close();
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		public FastScanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		public FastScanner(String s) {
			try {
				br = new BufferedReader(new FileReader(s));
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		public String nextToken() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
				}
			}
			return st.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(nextToken());
		}

		public long nextLong() {
			return Long.parseLong(nextToken());
		}

		public double nextDouble() {
			return Double.parseDouble(nextToken());
		}
	}

	public static void main(String[] args) {
		new Main().run();
	}
}