Problem: E: Binary Sequence-Binary Sequence-

story

I love binaries Bonald.Brvin.Bnuth! He is known as Uncle Bnuth, who is studying the nature of binary sequences at Offtunford University! By the way, if my name "Bonald.Brvin.Bnuth" is binarized from ASCII code, it will be "1000010 1101111 1101110 1100001 1101100 1100100 101110 1000010 1110010 1110110 1101001 1101110 101110 1000010 1101110 1110101 1110100 1101000"! It's fun!

I'm looking forward to it from the morning because my disciples are going to do some interesting experiments today! What are you doing?

What! I want to discover some properties by continuing to rewrite binary strings! HM! This is the scent of an important discovery! Let's start the experiment! Let's summarize more detailed settings as sentences!

problem

Given a binary sequence of length n x = (x_1, ..., x_n) (x_i \ in \\ {0,1 \\}, i = 1, ..., n). For the binary string x, we define two functions f (x) and g (x) as follows.


f (x) = Σ_ {i = 1} ^ {n} x_i = x_1 + x_2 + ... + x_n
g (x) = Σ_ {i = 1} ^ {n-1} x_i x_ {i + 1} = x_1 x_2 + x_2 x_3 + ... x_ {n-1} x_n


Now, perform the following change operation on the binary string x q times. The jth change operation is given by l_j, r_j, b_j (1 \ leq l_j \ leq r_j \ leq n, b_j \ in \\ {0,1 \\}, j = 1, ..., q). This corresponds to the operation of replacing the l_jth to r_jths of the binary string x with b_j. Find f (x) --g (x) after each change operation.

Input format


n
x
q
l_1 r_1 b_1
...
l_q r_q b_q


The first line is given the integer n that represents the length of the binary column. The second line is given a string that represents the binary column x. The third line is given the integer q, which represents the number of queries. In the following q lines, the i-th line is given information about the i-th query l_i, r_i, b_i in this order, separated by blanks.

Constraint

* 2 \ leq n \ leq 100000
* x is a character string consisting of ‘0’ and ‘1’
* | x ​​| = n
* 1 \ leq q \ leq 100000
* 1 \ leq l_j \ leq r_j \ leq n, b_j \ in \\ {0,1 \\}, j = 1, ..., q



Output format

For each i = 1, ..., q, output the value of f (x) --g (x) after processing the i-th query on the i-line.

Input example 1


Ten
0101100110
3
3 3 1
1 6 0
2 5 1


Output example 1


2
1
2


Input example 2


8
00111100
3
8 8 1
4 5 0
7 8 1


Output example 2


2
3
2






Example

Input

10
0101100110
3
3 3 1
1 6 0
2 5 1


Output

2
1
2

Solution (in CPP):

Solution:
#include "bits/stdc++.h"

using namespace std;

//int N,M,K,L,R,H,W;
long long int N,M,K,L,R,H,W;

constexpr long long int MOD=1000000007;
//constexpr  int MOD=1000000007;
//constexpr int MOD=998244353;
//constexpr long long int MOD=998244353;

constexpr long double EPS=1e-8;
class Add_Segment_Tree {
	vector<long long int>v;
	vector<long long int>add;
	vector<long long int>modi;
	vector<int>l;
	vector<int>r;
	int num;
	long long int ret;
	void Left(int place) {
		if (place >= v.size() / 2) {
			l[place] = place - v.size() / 2;
			return;
		}
		Left(place * 2);
		Left(place * 2 + 1);
		l[place] = l[place * 2];
		return;
	}
	void Right(int place) {
		if (place >= v.size() / 2) {
			r[place] = place - v.size() / 2;
			return;
		}
		Right(place * 2);
		Right(place * 2 + 1);
		r[place] = r[place * 2 + 1];
		return;
	}
	long long int Update(int place) {
		if (place >= v.size() / 2) {
			return v[place];
		}
		v[place] = Update(place * 2) + Update(place * 2 + 1);
		return v[place];
	}
	void Modify(int a, int b, long long int num, int place) {
		if (l[place] >= a && r[place] <= b) {
			modi[place] = num * (r[place] - l[place] + 1);
			v[place] = num * (r[place] - l[place] + 1);
			add[place] = 0;
			return;
		}
		if (l[place] > b || r[place] < a)return;
		if (modi[place] != LLONG_MAX) {
			modi[place * 2] = modi[place * 2 + 1] = modi[place] / 2;
			v[place * 2] = v[place * 2 + 1] = modi[place] / 2;
			add[place * 2] = add[place * 2 + 1] = 0;
			modi[place] = LLONG_MAX;
		}
		add[place * 2] += add[place] / 2;
		add[place * 2 + 1] += add[place] / 2;
		add[place] = 0;
		Modify(a, b, num, place * 2);
		Modify(a, b, num, place * 2 + 1);
		v[place] = v[place * 2] + add[place * 2] + v[place * 2 + 1] + add[place * 2 + 1];
		return;
	}
	void Add(int a, int b, long long int num, int place) {
		if (l[place] >= a && r[place] <= b) {
			if (modi[place] != LLONG_MAX) {
				if (place * 2 < v.size()) {
					modi[place * 2] = modi[place * 2 + 1] = modi[place] / 2;
					v[place * 2] = v[place * 2 + 1] = modi[place] / 2;
					add[place * 2] = add[place * 2 + 1] = 0;
				}
				modi[place] = LLONG_MAX;
			}
			add[place] += num * (r[place] - l[place] + 1);
			return;
		}
		if (l[place] > b || r[place] < a)return;
		if (modi[place] != LLONG_MAX) {
			modi[place * 2] = modi[place * 2 + 1] = modi[place] / 2;
			v[place * 2] = v[place * 2 + 1] = modi[place] / 2;
			add[place * 2] = add[place * 2 + 1] = 0;
			modi[place] = LLONG_MAX;
		}
		add[place * 2] += add[place] / 2;
		add[place * 2 + 1] += add[place] / 2;
		add[place] = 0;
		Add(a, b, num, place * 2);
		Add(a, b, num, place * 2 + 1);
		v[place] = v[place * 2] + add[place * 2] + v[place * 2 + 1] + add[place * 2 + 1];
		return;
	}
	void Sum(int a, int b, int place) {
		if (l[place] >= a && r[place] <= b) {
			if (modi[place] != LLONG_MAX) {
				if (place * 2 < v.size()) {
					modi[place * 2] = modi[place * 2 + 1] = modi[place] / 2;
					v[place * 2] = v[place * 2 + 1] = modi[place] / 2;
					add[place * 2] = add[place * 2 + 1] = 0;
				}
				modi[place] = LLONG_MAX;
			}
			ret += v[place] + add[place];
			return;
		}
		if (l[place]>b || r[place]<a) return;
		if (modi[place] != LLONG_MAX) {
			modi[place * 2] = modi[place * 2 + 1] = modi[place] / 2;
			v[place * 2] = v[place * 2 + 1] = modi[place] / 2;
			add[place * 2] = add[place * 2 + 1] = 0;
			modi[place] = LLONG_MAX;
		}
		add[place * 2] += add[place] / 2;
		add[place * 2 + 1] += add[place] / 2;
		add[place] = 0;
		Sum(a, b, place * 2);
		Sum(a, b, place * 2 + 1);
		v[place] = v[place * 2] + add[place * 2] + v[place * 2 + 1] + add[place * 2 + 1];
		return;
	}
public:
	Add_Segment_Tree(int n) {
		n++;
		num = 1;
		while (num < n * 2) {
			num *= 2;
		}
		l.resize(num);
		r.resize(num);
		v.resize(num, 0);
		add.resize(num, 0);
		modi.resize(num, LLONG_MAX);
		Left(1);
		Right(1);
	}
	void Insert(int place, long long int num, bool update) {
		place += v.size() / 2;
		v[place] = num;
		if (!update)return;
		place /= 2;
		while (place) {
			v[place] = v[place * 2] + v[place * 2 + 1];
			place /= 2;
		}
	}
	void Modify(int a, int b, long long int num) {
		Modify(a, b, num, 1);
	}
	void Add(int a, int b, long long int num) {
		Add(a, b, num, 1);
	}
	void Init() {
		Update(1);
	}
	long long int Sum(int a, int b) {
		ret = 0;
		Sum(a, b, 1);
		return ret;
	}
};
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	cin>>N;
	string s;
	cin>>s;
	cin>>K;
	Add_Segment_Tree sga(N+2);
	Add_Segment_Tree sgb(N+2);
	for(int i=0;i<N;i++){
		if(s[i]=='1')sga.Modify(i+1,i+1,1);
		if(i&&s[i]=='1'&&s[i-1]=='1')sgb.Modify(i+1,i+1,1);
	}
	for(int i=0;i<K;i++){
		cin>>L>>R>>M;
		sga.Modify(L,R,M);
		sgb.Modify(L+1,R,M);
		if(sga.Sum(L-1,L-1)==sga.Sum(L,L)&&M)sgb.Modify(L,L,1);
		else sgb.Modify(L,L,0);
		if(sga.Sum(R,R)==sga.Sum(R+1,R+1)&&M)sgb.Modify(R+1,R+1,1);
		else sgb.Modify(R+1,R+1,0);
		cout<<sga.Sum(0,N)-sgb.Sum(0,N)<<endl;
	}
	return 0;
}