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 C++14 (GCC 5.4.1) (judge verdict: Runtime Error)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

#define ll long long
#define ull unsigned long long
#define db long double
#define pb push_back
#define ppb pop_back
#define F first
#define S second
#define mp make_pair
#define all(x) (x).begin(), (x).end()

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef vector <int> vi;
typedef vector <ll> vll;

typedef tree <pii, null_type, less <pii>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;

const int N = 200003, K = 600;
int n, a[N], q, ind[N], dp[N], f[N];
pii query[N], p[N];
vi vec[N];

struct block {
	vector <pii> v, tmp_v;
	vi s, ord, tmp;
	int suf = N, val = -1;
	void add(int x) {
		for (int i = suf; i < (int)v.size(); i++) {
			v[i].F = val;
		}
		suf = N, val = -1;
		int l = p[x].F, r = p[x].S;
		v.pb({r, l});
		s.pb(dp[l - 1] - f[l - 1]);
		for (int i = (int)s.size() - 2; i >= 0; i--) {
			s[i] = min(s[i], s[i + 1]);
		}
	}
	int get(int x) {
		if (v.empty()) {
			return N;
		}
		int L = p[x].F, R = p[x].S;
		int pos = lower_bound(all(v), mp(L - 1, 0)) - v.begin();
		if (pos < suf) {
			if (pos == (int)v.size()) {
				return N;
			}
			suf = pos, val = R;
			return s[pos];
		}	else {
			if (val >= L - 1) {
				val = R;
				return s[suf];
			}	else {
				return N;
			}
		}
	}
	int naive_get(int x) {
		if (v.empty()) {
			return N;
		}
		int L = p[x].F, R = p[x].S, res = N;
		for (int i = 0; i < (int)v.size(); i++) {
			if (i >= suf) {
				v[i].F = val;
			}
			if (v[i].S <= L && v[i].F >= L - 1) {
				res = min(res, dp[v[i].S - 1] - f[v[i].S - 1]);
				v[i].F = R;
				tmp.pb(i);
			}	else {
				ord.pb(i);
			}
		}
		suf = N, val = -1;
		for (int i = 0; i < (int)ord.size(); i++) {
			tmp_v.pb(v[ord[i]]);
		}
		for (int i = 0; i < (int)tmp.size(); i++) {
			tmp_v.pb(v[tmp[i]]);
		}
		v = tmp_v;
		ord.clear();
		tmp.clear();
		tmp_v.clear();
		for (int i = (int)s.size() - 1; i >= 0; i--) {
			if (i == (int)s.size() - 1) {
				s[i] = dp[v[i].S - 1] - f[v[i].S - 1];
			}	else {
				s[i] = min(s[i + 1], dp[v[i].S - 1] - f[v[i].S - 1]);
			}
		}
		return res;
	}
	void debug() {
		cerr << "suf val " << suf << ' ' << val << '\n';
		for (int i = 0; i < (int)v.size(); i++) {
			cerr << "(" << v[i].S << ' ' << v[i].F << ")";
			if (i < (int)v.size() - 1) {
				cout << ", ";
			}
		}
		cerr << '\n';
	}
};

block b[N / K];

int main() {
	ios_base::sync_with_stdio(false), cin.tie(NULL);
	#ifdef LOCAL
		freopen("input.txt", "r", stdin);
	#endif
	
	cin >> n;
	int s = 0;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		f[i] = f[i - 1] + (a[i] == 0) - (a[i] == 1);
		s += a[i];
	}
	cin >> q;
	for (int i = 1; i <= q; i++) {
		int l, r;
		cin >> l >> r;
		p[i] = {l, r};
		vec[r].pb(i);
		query[i - 1] = {l, i};
	}
	sort(query, query + q);
	for (int i = 0; i < q; i++) {
		ind[query[i].S] = i;
	}
	for (int i = 1; i <= n; i++) {
		int res = N;
		for (int j : vec[i]) {
			b[ind[j] / K].add(j);
			for (int k = 0; k < N / K; k++) {
				int last = min(q - 1, K * (k + 1) - 1);
				if (query[last].F <= p[j].F) {
					res = min(res, b[k].get(j));
				}	else {
					res = min(res, b[k].naive_get(j));
					break;
				}
			}
		}
		dp[i] = min(dp[i - 1], res + f[i]);
		//b[0].debug();
		//cerr << "dp[" << i << "] = " << dp[i] << '\n';
	}
	cout << dp[n] + s;
}