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 Rust (1.15.1) (judge verdict: Accepted)

use std::io::*;
use std::str::FromStr;

#[allow(dead_code)]
fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

#[allow(dead_code)]
#[derive(Clone)]
struct Node {
    v: i32,
}
#[allow(dead_code)]
impl Node {
    fn new(v: i32) -> Node {
        Node { v: v }
    }
    fn default_value() -> Node {
        Node {
            v: i32::min_value(),
        }
    }
}
#[allow(dead_code)]
fn merge(left: &Node, right: &Node) -> Node {
    Node::new(std::cmp::max(left.v, right.v))
}

#[allow(dead_code)]
struct SegmentTree {
    max_depth: usize,
    data: Vec<Node>,
}
#[allow(dead_code)]
impl SegmentTree {
    fn new(n: usize) -> SegmentTree {
        let mut max_depth = 0;
        while (1 << max_depth) < n {
            max_depth += 1;
        }
        SegmentTree {
            max_depth: max_depth,
            data: vec![Node::default_value(); 1 << (max_depth + 1)],
        }
    }
    fn set(&mut self, index: usize, value: &Node) {
        let mut target = (1 << self.max_depth) + index;
        self.data[target] = value.clone();
        for _ in 0..self.max_depth {
            target >>= 1;
            self.data[target] = merge(&self.data[target * 2], &self.data[target * 2 + 1]);
        }
    }
    fn get(&self, left: usize, right: usize) -> Node {
        assert!(left < right);
        self.in_get(0, 1, left, right)
    }
    fn in_get(&self, depth: usize, node: usize, left: usize, right: usize) -> Node {
        let width = 1 << (self.max_depth - depth);
        let index = node - (1 << depth);
        let node_left = index * width;
        let node_mid = node_left + (width >> 1);
        if right - left == width && left == node_left {
            return self.data[node].clone();
        } else if right <= node_mid {
            return self.in_get(depth + 1, node * 2, left, right);
        } else if node_mid <= left {
            return self.in_get(depth + 1, node * 2 + 1, left, right);
        }
        merge(
            &self.in_get(depth + 1, node * 2, left, node_mid),
            &self.in_get(depth + 1, node * 2 + 1, node_mid, right),
        )
    }
}

#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
enum Event {
    In(usize, usize),
    Out(usize, usize),
}

fn naive(bseq: &Vec<i32>, query: &Vec<(usize, usize)>) -> i32 {
    let n = bseq.len();
    let q = query.len();
    let mut ans = n as i32;
    for mask in 0..(1 << q) {
        let mut sum = 0;
        let mut aseq = vec![0; n];
        for i in 0..q {
            if ((mask >> i) & 1) != 1 {
                continue;
            }
            for j in query[i].0..query[i].1 {
                aseq[j] = 1;
            }
        }
        for i in 0..n {
            if aseq[i] != bseq[i] {
                sum += 1;
            };
        }
        ans = std::cmp::min(ans, sum);
    }
    ans
}

fn solve(bseq: &Vec<i32>, query: &Vec<(usize, usize)>) -> i32 {
    let n = bseq.len();
    let q = query.len();
    let mut zeros = vec![0 as i32; n + 1];
    let mut ones = vec![0 as i32; n + 1];
    for i in 0..n {
        zeros[i + 1] = zeros[i] + (bseq[i] ^ 1);
        ones[i + 1] = ones[i] + bseq[i];
    }
    let mut events = vec![];
    for i in 0..q {
        events.push(Event::In(query[i].0, query[i].1));
        events.push(Event::Out(query[i].0, query[i].1));
    }
    events.sort_by(|a, b| {
        let lhs = match a {
            &Event::In(l, _r) => l,
            &Event::Out(_l, r) => r,
        };
        let rhs = match b {
            &Event::In(l, _r) => l,
            &Event::Out(_l, r) => r,
        };
        if lhs == rhs {
            b.cmp(a)
        } else {
            lhs.cmp(&rhs)
        }
    });
    // println!("{:?}", events);

    let mut stree = SegmentTree::new(n + 2);
    let mut unconflict: i32 = 0;
    for event in events.iter() {
        if let &Event::In(l, r) = event {
            let v = std::cmp::max(stree.get(l, r).v, unconflict - ones[l] + zeros[l]);
            stree.set(r - 1, &Node::new(v));
        } else if let &Event::Out(_l, r) = event {
            unconflict = std::cmp::max(unconflict, stree.get(r - 1, r).v + ones[r] - zeros[r]);
        }
    }
    unconflict += zeros[n];
    n as i32 - unconflict
}
fn main() {
    let n: usize = read();
    let mut bseq = vec![0 as i32; n];
    for i in 0..n {
        bseq[i] = read();
    }
    let q: usize = read();
    let mut query = vec![(0 as usize, 0 as usize); q];
    for i in 0..q {
        query[i] = (read(), read());
        query[i].0 -= 1;
    }
    let ans = solve(&bseq, &query);
    println!("{}", ans);
    // assert!(ans == naive(&bseq, &query));
}

#[allow(dead_code)]
struct XorShift {
    x: u32,
    y: u32,
    z: u32,
    w: u32,
}
#[allow(dead_code)]
impl XorShift {
    fn new() -> XorShift {
        XorShift {
            x: 0x34fb2383,
            y: 0x327328fa,
            z: 0xabd4b54a,
            w: 0xa9dba8d1,
        }
    }
    fn seed(s: u32) -> XorShift {
        let mut rnd = XorShift::new();
        rnd.w = s;
        rnd
    }
    fn xor128(&mut self) -> u32 {
        let t = self.x ^ (self.x << 11);
        self.x = self.y;
        self.y = self.z;
        self.z = self.w;
        self.w = (self.w ^ (self.w >> 19)) ^ (t ^ (t >> 8));
        self.w
    }
    fn next_i32(&mut self, r: i32) -> i32 {
        (self.xor128() % r as u32) as i32
    }
    fn next_i32_lr(&mut self, l: i32, r: i32) -> i32 {
        self.next_i32(r - l + 1) + l
    }
    fn next_i64(&mut self, r: i64) -> i64 {
        ((((self.xor128() as u64) << 32) + self.xor128() as u64) % r as u64) as i64
    }
    fn next_i64_lr(&mut self, l: i64, r: i64) -> i64 {
        self.next_i64(r - l + 1) + l
    }
    fn next_f64(&mut self, r: f64) -> f64 {
        (self.xor128() as f64) / (0xffffffffu32 as f64) * r
    }
    fn next_f64_lr(&mut self, l: f64, r: f64) -> f64 {
        self.next_f64(r - l) + l
    }
}

#[test]
fn test() {
    let mut rnd = XorShift::new();
    for _iter in 0..1000 {
        let n = rnd.next_i32_lr(2, 20) as usize;
        let mut bseq = vec![0; n];
        for i in 0..n {
            bseq[i] = rnd.next_i32_lr(0, 1);
        }
        let q = rnd.next_i32_lr(2, 10) as usize;
        let mut query = vec![(0 as usize, 0 as usize); q];
        for i in 0..q {
            query[i].0 = rnd.next_i32_lr(0, n as i32 - 1) as usize;
            query[i].1 = rnd.next_i32_lr(query[i].0 as i32 + 1, n as i32) as usize;
        }
        println!("{}", n);
        for i in 0..n {
            print!("{} ", bseq[i]);
        }
        println!("");
        println!("{}", q);
        for i in 0..q {
            println!("{} {}", query[i].0 + 1, query[i].1);
        }
        assert!(solve(&bseq, &query) == naive(&bseq, &query));
    }
}