Problem:
プログラミングコンテストの合宿で出す問題のアイディアが出ずに困っていたイクタ君は、ある日友人に相談した。
イクタ君「こういうアルゴリズムを使わないと解けないような問題が出したいんですけど、なにかありませんかね？」
友人「それではこういうものを考えたらいいんじゃないですか」
このようにしてその友人は以下のような問題の原案となるアイデアを考えてくれた。
2進数
A,B
が与えられた時、以下の様なクエリを処理せよ。
出力クエリ: max{
x
を2進数で表したときの、1の数 |
A ≤ x < A+B
}を出力
A変更クエリ:
A
の最下位ビットから
i
ビット目(0-origin)を反転
B変更クエリ:
B
の最下位ビットから
i
ビット目(0-origin)を反転
i
ビット目というのが 0-origin で表されていることに注意せよ。
つまり、
A
の最下位ビットから0ビット目とは最下位ビットを表す。
Input
入力は以下の形式で与えられる。
N
A
B
Q
1
...
Q
N
1行目にクエリの数N,2進数A, Bが与えられる。
2からN+1行目には以下の様なクエリが与えられる。
Q
A
i
B
i
Qが出力クエリを、A
i
,B
i
はそれぞれ
A
の最下位ビットから
i
ビット目、
B
の最下位ビットから
i
ビット目を反転させる変更クエリを表している。
Constraints
入力中の各変数は以下の制約を満たす。
1 ≤ N < 300,000
1 ≤ |A|,|B| ≤ 300,000
(
|A|
は
A
の長さ)
A
i
というクエリでは
0 ≤ i < |A|
B
i
というクエリでは
0 ≤ i < |B|
B
が0になることはない
Output
出力クエリごとに答えを1行に出力せよ。
Sample Input 1
4 10000 00101
Q
A 0
B 1
Q
Output for the Sample Input 1
3
4
最初の出力クエリでは
A=10000
,
B=00101
,
A+B=10101
なので求める
x
は10011
次の出力クエリでは
A=10001
,
B=00111
,
A+B=11000
なので求める
x
は10111
Sample Input 2
9 0110111101 0010100111
Q
B 4
Q
A 4
Q
B 9
Q
A 8
Q
Output for the Sample Input 2
9
9
9
10
9

Submitted solutions:

code_snippet: #include<iostream>
#include<string>
#include<algorithm>
using namespace std;

#define MAX_N 500000
string A, B;
int n, c, d, e, sum;
int a[MAX_N], b[MAX_N], ab[MAX_N];
char f[MAX_N];

int main() {
	cin >> n;
	cin >> A >> B;
	d = max(A.size(), B.size()) + 1;
	for (int i = 0; i < A.size(); i++)
	{
		if (A[i] == '1') { c = 1; }
		if (A[i] == '0') { c = 0; }
		a[A.size() - 1 - i] = c;
	}
	for (int i = 0; i < B.size(); i++)
	{
		if (B[i] == '1') { c = 1; }
		if (B[i] == '0') { c = 0; }
		b[B.size() - 1 - i] = c;
	}
	for (int i = 0; i < d; i++)
	{
		ab[i] += a[i] + b[i];
		if (ab[i] >= 2) {
			ab[i] -= 2; ab[i + 1]++;
		}
	}
	for (int i = 0; i < n; i++)
	{
		cin >> f[i];
		if (f[i] == 'A') {
			cin >> e;
			if (a[e] == 1)
			{
				a[e] = 0;
				ab[e]--;
				if (ab[e] < 0)
				{
					while (e < d)
					{
						ab[e + 1]--;
						ab[e] += 2;
						if (ab[e + 1] == 0) { break; }
						e++;
					}
				}
			}
			else
			{
				a[e] = 1;
				ab[e]++;
				if (ab[e] >= 2)
				{
					while (e < d)
					{
						ab[e + 1]++;
						ab[e] -= 2;
						if (ab[e + 1] == 1) { break; }
						e++;
					}
				}
			}
		}
		if (f[i] == 'B')
		{
			cin >> e;
			if (b[e] == 1)
			{
				b[e] = 0;
				ab[e]--;
				if (ab[e] < 0)
				{
					while (e < d)
					{
						ab[e + 1]--;
						ab[e] += 2;
						if (ab[e + 1] == 0) { break; }
						e++;
					}
				}
			}
			else
			{
				b[e] = 1;
				ab[e]++;
				if (ab[e] >= 2)
				{
					while (e < d)
					{
						ab[e + 1]++;
						ab[e] -= 2;
						if (ab[e + 1] == 1) { break; }
						e++;
					}
				}
			}
		}
		if (f[i] == 'Q') {
			if (i >= 1) {
				if (f[i - 1] == 'Q') {
					cout << sum << endl; goto H;
				}
			}
			sum = 0;
			for (int j = d; j >= 0; j--)
			{
				if (a[j] != ab[j])
				{
					sum += j;
					break;
				}
				if (a[j] == 1) {
					sum++;
				}
			}
			cout << sum << endl;
		H:;
		}
	}
	return 0;
}
accuracy: 1
time_ms: 2150
memory_kb: 9424
final_rank: 17

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

template<typename T>struct BIT{
    int n; T all=0; vector<T> val;
    BIT(int _n=0):n(_n),val(_n+10){}
    void clear(){val.assign(n+10,0); all=T();}
    void add(int i,T x){
        for(i++;i<=n;i+=(i&-i))val[i]=val[i]+x;
        all+=x;
    }
    T sum(int i){
        T res=0;
        for(;i;i-=(i&-i))res+=val[i];
        return res;
    }
    T sum(int L,int R){return sum(R)-sum(L);} // [L,R)

    int lower_bound(T x){
        int ret=0,len=1;
        while(2*len<=n)len<<=1;
        for(;len>=1;len>>=1){
            if(ret+len<=n and val[ret+len]<x){
                ret+=len;
                x-=val[ret];
            }
        }
        return ret;
    }
};

/**
 * @brief Binary Indexed Tree
 */

int main() {
    int Q;
    string SA, SB;
    cin >> Q >> SA >> SB;
    int N = max(SA.size(),SB.size());
    vector<int> A(N,0), B(N,0);
    rep(i,0,SA.size()) A[N-1-i] = SA[SA.size()-1-i]-'0';
    rep(i,0,SB.size()) B[N-1-i] = SB[SB.size()-1-i]-'0';
    BIT<int> Seg(N);
    rep(i,0,N) Seg.add(i,A[i]);
    set<int> BS, AND, NOR;
    rep(i,0,N) {
        if (B[i] == 1) BS.insert(i);
        if (A[i] == 1 && B[i] == 1) AND.insert(i);
        if (A[i] == 0 && B[i] == 0) NOR.insert(i);
    }
    AND.insert(N), NOR.insert(N);
    while(Q--) {
        char C;
        cin >> C;
        if (C == 'Q') {
            int ID = *BS.begin();
            bool check = false;
            if (A[ID] == 0) {
                if (*AND.lower_bound(ID) < *NOR.lower_bound(ID)) check = true;
            }
            int ANS = Seg.sum(0,ID+1) + (N-ID-1);
            if (check) ANS++;
            cout << ANS << endl;
        }
        if (C == 'A') {
            int ID;
            cin >> ID;
            ID = N-1-ID;
            if (A[ID] == 0) {
                A[ID] = 1;
                Seg.add(ID,1);
                if (B[ID] == 0) NOR.erase(ID);
                else AND.insert(ID);
            }
            else {
                A[ID] = 0;
                Seg.add(ID,-1);
                if (B[ID] == 0) NOR.insert(ID);
                else AND.erase(ID);
            }
        }
        if (C == 'B') {
            int ID;
            cin >> ID;
            ID = N-1-ID;
            if (B[ID] == 0) {
                B[ID] = 1;
                BS.insert(ID);
                if (A[ID] == 0) NOR.erase(ID);
                else AND.insert(ID);
            }
            else {
                B[ID] = 0;
                BS.erase(ID);
                if (A[ID] == 0) NOR.insert(ID);
                else AND.erase(ID);
            }
        }
    }
}
accuracy: 1
time_ms: 310
memory_kb: 21308
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll=long long;

struct fenwick_tree {

  public:
    fenwick_tree() : _n(0) {}
    explicit fenwick_tree(int n) : _n(n), data(n) {}

    void add(int p, ll x) {
        assert(0 <= p && p < _n);
        p++;
        while (p <= _n) {
            data[p - 1] += x;
            p += p & -p;
        }
    }

    ll sum(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        return sum(r) - sum(l);
    }

  private:
    int _n;
    std::vector<ll> data;

    ll sum(int r) {
        ll s = 0;
        while (r > 0) {
            s += data[r - 1];
            r -= r & -r;
        }
        return s;
    }
};

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    ll N;
    string A,B;
    cin>>N>>A>>B;
    ll n=max(A.size(),B.size());
    reverse(A.begin(),A.end());
    for(int i=A.size();i<n;i++)A.push_back('0');

    reverse(B.begin(),B.end());
    for(int i=B.size();i<n;i++)B.push_back('0');
    fenwick_tree F(n);
    vector<set<int>> SM(2);
    set<int> SB;
    for(int i=0;i<n;i++){
        if(A[i]=='1'){
            F.add(i,1);
        }
        if(B[i]=='1'){
            SB.insert(i);
        }
        if(A[i]==B[i])SM[A[i]-'0'].insert(i);
    }
    SM[0].insert(-100);
    SM[1].insert(-150);
    for(int q=0;q<N;q++){
        char C;
        cin>>C;
        if(C=='Q'){
            int mb=*(prev(SB.end()));
            if(A[mb]=='1'){
                cout<<F.sum(mb+1,n)+mb+1<<endl;
            }
            else{
                int p=*(prev(SM[0].lower_bound(mb)));
                int q=*(prev(SM[1].lower_bound(mb)));
                int an=F.sum(mb+1,n);
                if(q>p)an+=mb+1;
                else an+=mb;
                cout<<an<<endl;
            }
        }
        else if(C=='A'){
            int i;
            cin>>i;
            if(A[i]=='1'){
                if(B[i]=='1'){
                    SM[1].erase(i);
                }
                else{
                    SM[0].insert(i);
                }
                F.add(i,-1);
                A[i]='0';
            }
            else{
                if(B[i]=='1'){
                    SM[1].insert(i);
                }
                else{
                    SM[0].erase(i);
                }
                F.add(i,1);
                A[i]='1';
            }
        }
        else{
            int i;
            cin>>i;
            if(B[i]=='1'){
                if(A[i]=='1'){
                    SM[1].erase(i);
                }
                else{
                    SM[0].insert(i);
                }
                SB.erase(i);
                B[i]='0';
            }
            else{
                if(A[i]=='1'){
                    SM[1].insert(i);
                }
                else{
                    SM[0].erase(i);
                }
                SB.insert(i);
                B[i]='1';
            }
        }
    }
}
accuracy: 1
time_ms: 280
memory_kb: 19984
final_rank: 3

code_snippet: #include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#pragma GCC target("avx")
#pragma GCC optimize("O3")
using namespace std;

int main() {
	// step #1. read input
	cin.tie(0);
	ios_base::sync_with_stdio(false);
	int Q; string A, B;
	cin >> Q >> A >> B;
	
	// step #2. transform to bitset
	const int M = 63;
	int L = max(A.size(), B.size()) / M + 1;
	vector<uint64_t> seqa(L), seqb(L);
	for (int i = 0; i < int(A.size()); i++) {
		if (A[A.size() - i - 1] == '1') {
			seqa[i / M] |= 1ULL << (i % M);
		}
	}
	for (int i = 0; i < int(B.size()); i++) {
		if (B[B.size() - i - 1] == '1') {
			seqb[i / M] |= 1ULL << (i % M);
		}
	}
	
	// step #3. process query
	int last_answer = -1;
	for (int id = 1; id <= Q; id++) {
		string tp;
		cin >> tp;
		if (tp == "A") {
			int idx;
			cin >> idx;
			seqa[idx / M] ^= 1ULL << (idx % M);
			last_answer = -1;
		}
		if (tp == "B") {
			int idx;
			cin >> idx;
			seqb[idx / M] ^= 1ULL << (idx % M);
			last_answer = -1;
		}
		if (tp == "Q" && last_answer == -1) {
			vector<uint64_t> seqc(L);
			for (int i = 0; i < L; i++) {
				seqc[i] += seqa[i] + seqb[i];
				if (((seqc[i] >> M) & 1ULL) == 1ULL) {
					seqc[i] ^= 1ULL << M;
					seqc[i + 1] ^= 1ULL;
				}
			}
			int pos = -1;
			for (int i = L - 1; i >= 0; i--) {
				if (seqa[i] != seqc[i]) {
					pos = i;
					break;
				}
			}
			int subpos = 63 - __builtin_clzll(seqa[pos] ^ seqc[pos]);
			int answer = pos * M + subpos;
			answer += __builtin_popcountll(seqa[pos] & ~((1ULL << subpos) - 1ULL));
			for (int i = pos + 1; i < L; i++) {
				answer += __builtin_popcountll(seqa[i]);
			}
			last_answer = answer;
		}
		if (tp == "Q") {
			cout << last_answer << '\n';
		}
	}
	
	return 0;
}
accuracy: 1
time_ms: 1470
memory_kb: 4132
final_rank: 11

code_snippet: #include <string>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

int main() {
	// step #1. read input
	cin.tie(0);
	ios_base::sync_with_stdio(false);
	int Q; string A, B;
	cin >> Q >> A >> B;
	
	// step #2. transform to bitset
	const int M = 63;
	int L = max(A.size(), B.size()) / M + 1;
	vector<uint64_t> seqa(L), seqb(L);
	for (int i = 0; i < int(A.size()); i++) {
		if (A[A.size() - i - 1] == '1') {
			seqa[i / M] |= 1ULL << (i % M);
		}
	}
	for (int i = 0; i < int(B.size()); i++) {
		if (B[B.size() - i - 1] == '1') {
			seqb[i / M] |= 1ULL << (i % M);
		}
	}
	
	// step #3. process query
	int last_answer = -1;
	for (int id = 1; id <= Q; id++) {
		string tp;
		cin >> tp;
		if (tp == "A") {
			int idx;
			cin >> idx;
			seqa[idx / M] ^= 1ULL << (idx % M);
			last_answer = -1;
		}
		if (tp == "B") {
			int idx;
			cin >> idx;
			seqb[idx / M] ^= 1ULL << (idx % M);
			last_answer = -1;
		}
		if (tp == "Q" && last_answer == -1) {
			vector<uint64_t> seqc(L);
			for (int i = 0; i < L; i++) {
				seqc[i] += seqa[i] + seqb[i];
				if (((seqc[i] >> M) & 1ULL) == 1ULL) {
					seqc[i] ^= 1ULL << M;
					seqc[i + 1] ^= 1ULL;
				}
			}
			int pos = -1;
			for (int i = L - 1; i >= 0; i--) {
				if (seqa[i] != seqc[i]) {
					pos = i;
					break;
				}
			}
			int subpos = 63 - __builtin_clzll(seqa[pos] ^ seqc[pos]);
			int answer = pos * M + subpos;
			answer += __builtin_popcountll(seqa[pos] & ~((1ULL << subpos) - 1ULL));
			for (int i = pos + 1; i < L; i++) {
				answer += __builtin_popcountll(seqa[i]);
			}
			last_answer = answer;
		}
		if (tp == "Q") {
			cout << last_answer << '\n';
		}
	}
	
	return 0;
}
accuracy: 1
time_ms: 1830
memory_kb: 4020
final_rank: 14

code_snippet: #line 2 "/home/hotman78/vscode/ICPC/library/cpplib/util/template.hpp"
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx2")
#include<bits/stdc++.h>
using namespace std;
#line 1 "/home/hotman78/vscode/ICPC/library/cpplib/util/ioutil.hpp"
// template <class Head,class... Args>
// std::ostream& output(std::ostream& out,const Head& head,const Args&... args){
//     out>>head;
//     return output(head,args...);
// }
// template <class Head>
// std::ostream& output(std::ostream& out,const Head& head){
//     out>>head;
//     return out;
// }

template<typename T,typename E>
std::ostream& operator<<(std::ostream& out,std::pair<T,E>v){
    out<<"("<<v.first<<","<<v.second<<")";return out;
}

// template <class... Args>
// ostream& operator<<(ostream& out,std::tuple<Args...>v){
//     std::apply(output,v);
//     return out;
// }
#line 8 "/home/hotman78/vscode/ICPC/library/cpplib/util/template.hpp"
struct __INIT__{__INIT__(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(15);}}__INIT__;
typedef long long lint;
#define INF (1LL<<60)
#define IINF (1<<30)
#define EPS (1e-10)
#define endl ('\n')
typedef vector<lint> vec;
typedef vector<vector<lint>> mat;
typedef vector<vector<vector<lint>>> mat3;
typedef vector<string> svec;
typedef vector<vector<string>> smat;
template<typename T>using V=vector<T>;
template<typename T>using VV=V<V<T>>;
template<typename T>inline void output(T t){bool f=0;for(auto i:t){cout<<(f?" ":"")<<i;f=1;}cout<<endl;}
template<typename T>inline void output2(T t){for(auto i:t)output(i);}
template<typename T>inline void debug(T t){bool f=0;for(auto i:t){cerr<<(f?" ":"")<<i;f=1;}cerr<<endl;}
template<typename T>inline void debug2(T t){for(auto i:t)debug(i);}
#define loop(n) for(long long _=0;_<(long long)(n);++_)
#define _overload4(_1,_2,_3,_4,name,...) name
#define __rep(i,a) repi(i,0,a,1)
#define _rep(i,a,b) repi(i,a,b,1)
#define repi(i,a,b,c) for(long long i=(long long)(a);i<(long long)(b);i+=c)
#define rep(...) _overload4(__VA_ARGS__,repi,_rep,__rep)(__VA_ARGS__)
#define _overload3_rev(_1,_2,_3,name,...) name
#define _rep_rev(i,a) repi_rev(i,0,a)
#define repi_rev(i,a,b) for(long long i=(long long)(b)-1;i>=(long long)(a);--i)
#define rrep(...) _overload3_rev(__VA_ARGS__,repi_rev,_rep_rev)(__VA_ARGS__)

// #define rep(i,...) for(auto i:range(__VA_ARGS__)) 
// #define rrep(i,...) for(auto i:reversed(range(__VA_ARGS__)))
// #define repi(i,a,b) for(lint i=lint(a);i<(lint)(b);++i)
// #define rrepi(i,a,b) for(lint i=lint(b)-1;i>=lint(a);--i)
// #define irep(i) for(lint i=0;;++i)
// inline vector<long long> range(long long n){if(n<=0)return vector<long long>();vector<long long>v(n);iota(v.begin(),v.end(),0LL);return v;}
// inline vector<long long> range(long long a,long long b){if(b<=a)return vector<long long>();vector<long long>v(b-a);iota(v.begin(),v.end(),a);return v;}
// inline vector<long long> range(long long a,long long b,long long c){if((b-a+c-1)/c<=0)return vector<long long>();vector<long long>v((b-a+c-1)/c);for(int i=0;i<(int)v.size();++i)v[i]=i?v[i-1]+c:a;return v;}
// template<typename T>inline T reversed(T v){reverse(v.begin(),v.end());return v;}
#define all(n) begin(n),end(n)
template<typename T,typename E>bool chmin(T& s,const E& t){bool res=s>t;s=min<T>(s,t);return res;}
template<typename T,typename E>bool chmax(T& s,const E& t){bool res=s<t;s=max<T>(s,t);return res;}
// const array<lint,8> dx={1,0,-1,0,1,1,-1,-1};
// const array<lint,8> dy={0,1,0,-1,1,-1,1,-1};
// const string ds="RDLU";
#define SUM(v) accumulate(all(v),0LL)
#if __cplusplus>=201703L
    template<typename T,typename ...Args>auto make_vector(T x,int arg,Args ...args){if constexpr(sizeof...(args)==0)return vector<T>(arg,x);else return vector(arg,make_vector<T>(x,args...));}
#endif
#define extrep(v,...) for(auto v:__MAKE_MAT__({__VA_ARGS__}))
#define bit(n,a) ((n>>a)&1)
vector<vector<long long>> __MAKE_MAT__(vector<long long> v){if(v.empty())return vector<vector<long long>>(1,vector<long long>());long long n=v.back();v.pop_back();vector<vector<long long>> ret;vector<vector<long long>> tmp=__MAKE_MAT__(v);for(auto e:tmp)for(long long i=0;i<n;++i){ret.push_back(e);ret.back().push_back(i);}return ret;}
using graph=vector<vector<int>>;
template<typename T>using graph_w=vector<vector<pair<int,T>>>;

#if __cplusplus>=201703L
    constexpr inline long long powll(long long a,long long b){long long res=1;while(b--)res*=a;return res;}
#endif

template<typename T,typename E>pair<T,E>& operator+=(pair<T,E>&s,const pair<T,E>&t){s.first+=t.first;s.second+=t.second;return s;}
template<typename T,typename E>pair<T,E>& operator-=(pair<T,E>&s,const pair<T,E>&t){s.first-=t.first;s.second-=t.second;return s;}
template<typename T,typename E>pair<T,E> operator+(const pair<T,E>&s,const pair<T,E>&t){auto res=s;return res+=t;}
template<typename T,typename E>pair<T,E> operator-(const pair<T,E>&s,const pair<T,E>&t){auto res=s;return res-=t;}
#define BEGIN_STACK_EXTEND(size) void * stack_extend_memory_ = malloc(size);void * stack_extend_origin_memory_;char * stack_extend_dummy_memory_ = (char*)alloca((1+(int)(((long long)stack_extend_memory_)&127))*16);*stack_extend_dummy_memory_ = 0;asm volatile("mov %%rsp, %%rbx\nmov %%rax, %%rsp":"=b"(stack_extend_origin_memory_):"a"((char*)stack_extend_memory_+(size)-1024));
#define END_STACK_EXTEND asm volatile("mov %%rax, %%rsp"::"a"(stack_extend_origin_memory_));free(stack_extend_memory_);
#line 3 "/home/hotman78/vscode/ICPC/library/cpplib/alga/maybe.hpp"

/**
 * @brief Maybe
 * @see https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%8A%E3%83%89_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)#Maybe%E3%83%A2%E3%83%8A%E3%83%89
 */

template<typename T>
struct maybe{
    bool _is_none;
    T val;
    maybe():_is_none(true){}
    maybe(T val):_is_none(false),val(val){}
    T unwrap()const{
        assert(!_is_none);
        return val;
    }
    T unwrap_or(T e)const{
        return _is_none?e:val;
    }
    bool is_none()const{return _is_none;}
    bool is_some()const{return !_is_none;}
};

template<typename T,typename F>
auto expand(F op){
    return [&op](const maybe<T>& __s,const maybe<T>& __t)->maybe<T>{
        if(__s.is_none())return __t;
        if(__t.is_none())return __s;
        return maybe<T>(op(__s.unwrap(),__t.unwrap()));
    };
}
#line 4 "/home/hotman78/vscode/ICPC/library/cpplib/segment_tree/segment_tree.hpp"

/**
 * @brief セグメント木
 * @see https://en.wikipedia.org/wiki/Segment_tree
 */

template<typename T,typename F>
class segment_tree{
    using i64=long long;
    struct node;
    using np=node*;
    struct node{
        maybe<T>val;
        np ch[2]={nullptr,nullptr};
        node(maybe<T> val=maybe<T>()):val(val){}
    };
    np root=new node();
    i64 n=1;
    i64 sz;
    F op;
	public:
    segment_tree(){}
	segment_tree(i64 sz,F op=F()):sz(sz),op(op){
		while(n<=sz)n<<=1;
	}
    maybe<T> get(i64 a,i64 b){
        return get(a,b,0,n,root);
    }
    void apply(i64 x,T val){
        apply(x,val,0,n,root);
    }
    void apply_left(i64 x,T val){
        apply_left(x,val,0,n,root);
    }
    void change(i64 x,T val){
        change(x,val,0,n,root);
    }
    maybe<T> get(i64 a,i64 b,i64 l,i64 r,np t){
        if(!t)return maybe<T>();
        auto f=expand<T,F>(op);
        if(r<=a||b<=l)return maybe<T>();
        if(a<=l&&r<=b){
            return t->val;
        }
        const i64 m=(l+r)/2;
        return f(get(a,b,l,m,t->ch[0]),get(a,b,m,r,t->ch[1]));
    }
    void apply(i64 x,T val,i64 l,i64 r,np t){
        auto f=expand<T,F>(op);
        if(!t->ch[0])t->ch[0]=new node();
        if(!t->ch[1])t->ch[1]=new node();
        if(l<=x&&x<r){
            t->val=f(t->val,val);
            const i64 m=(l+r)/2;
            if(r-l>1){
                apply(x,val,l,m,t->ch[0]);
                apply(x,val,m,r,t->ch[1]);
            }
        }
    }
    void apply_left(i64 x,T val,i64 l,i64 r,np t){
        if(!t->ch[0])t->ch[0]=new node();
        if(!t->ch[1])t->ch[1]=new node();
        auto f=expand<T,F>(op);
        if(l<=x&&x<r){
            t->val=f(val,t->val);
            i64 m=(l+r)/2;
            if(r-l>1){
                apply_left(x,val,l,m,t->ch[0]);
                apply_left(x,val,m,r,t->ch[1]);
            }
        }
    }
    maybe<T> change(i64 x,const T& val,i64 l,i64 r,np t){
        if(!t->ch[0])t->ch[0]=new node();
        if(!t->ch[1])t->ch[1]=new node();
        auto f=expand<T,F>(op);
        if(l<=x&&x<r){
            if(r-l>1){
                const i64 m=(l+r)/2;
                auto p=change(x,val,l,m,t->ch[0]);
                auto q=change(x,val,m,r,t->ch[1]);
                return t->val=f(p,q);
            }else{
                return t->val=val;
            }
        }
        return t->val;
    }
};
template<typename T>using plus_segment_tree=segment_tree<T,plus<T>>;
template<typename T>
struct MAX_F{
    T operator()(const T& s,const T& t){
        return max(s,t);
    }
};
template<typename T>using max_seg=segment_tree<T,MAX_F<T>>;
#line 3 "main.cpp"

int main(){
    lint m;
    cin>>m;
    string s,t;
    cin>>s>>t;
    set<lint>p,q;
    lint n=300000;
    plus_segment_tree<lint> seg(n);
    q.emplace(n);
    auto flip=[&](set<lint>&s,lint val){
        if(s.count(val))s.erase(s.find(val));
        else s.emplace(val);
    };
    reverse(all(s));
    while((int)s.size()<n)s+='0';
    reverse(all(s));
    reverse(all(t));
    while((int)t.size()<n)t+='0';
    reverse(all(t));

    rep(i,n){
        if(s[i]=='1'){
            seg.apply(i,1);
        }
        if(s[i]=='0'){
            flip(p,i);
        }
        if(t[i]=='1'){
            flip(p,i);
            flip(q,i);
        }
    }

    while(m--){
        string que;
        cin>>que;
        if(que=="Q"){
            lint tmp=*q.begin();
            lint ans=seg.get(0,tmp+1).unwrap_or(0)+(n-tmp-1)+(s[tmp]=='0'&&p.upper_bound(tmp)!=p.end()&&q.count(*p.upper_bound(tmp)));
            cout<<ans<<endl;
        }else if(que=="A"){
            lint i;
            cin>>i;
            i=n-1-i;
            s[i]=(1-(s[i]-'0'))+'0';
            flip(p,i);
            if(s[i]=='0'){
                seg.change(i,0);
            }else{
                seg.change(i,1);
            }
        }else{
            lint i;
            cin>>i;
            i=n-1-i;
            t[i]=(1-(t[i]-'0'))+'0';
            flip(p,i);
            flip(q,i);
        }
    }
}
accuracy: 1
time_ms: 330
memory_kb: 69008
final_rank: 12

code_snippet: #line 2 "/home/hotman78/vscode/ICPC/library/cpplib/util/template.hpp"
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx2")
#include<bits/stdc++.h>
using namespace std;
#line 1 "/home/hotman78/vscode/ICPC/library/cpplib/util/ioutil.hpp"
// template <class Head,class... Args>
// std::ostream& output(std::ostream& out,const Head& head,const Args&... args){
//     out>>head;
//     return output(head,args...);
// }
// template <class Head>
// std::ostream& output(std::ostream& out,const Head& head){
//     out>>head;
//     return out;
// }

template<typename T,typename E>
std::ostream& operator<<(std::ostream& out,std::pair<T,E>v){
    out<<"("<<v.first<<","<<v.second<<")";return out;
}

// template <class... Args>
// ostream& operator<<(ostream& out,std::tuple<Args...>v){
//     std::apply(output,v);
//     return out;
// }
#line 8 "/home/hotman78/vscode/ICPC/library/cpplib/util/template.hpp"
struct __INIT__{__INIT__(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(15);}}__INIT__;
typedef long long lint;
#define INF (1LL<<60)
#define IINF (1<<30)
#define EPS (1e-10)
#define endl ('\n')
typedef vector<lint> vec;
typedef vector<vector<lint>> mat;
typedef vector<vector<vector<lint>>> mat3;
typedef vector<string> svec;
typedef vector<vector<string>> smat;
template<typename T>using V=vector<T>;
template<typename T>using VV=V<V<T>>;
template<typename T>inline void output(T t){bool f=0;for(auto i:t){cout<<(f?" ":"")<<i;f=1;}cout<<endl;}
template<typename T>inline void output2(T t){for(auto i:t)output(i);}
template<typename T>inline void debug(T t){bool f=0;for(auto i:t){cerr<<(f?" ":"")<<i;f=1;}cerr<<endl;}
template<typename T>inline void debug2(T t){for(auto i:t)debug(i);}
#define loop(n) for(long long _=0;_<(long long)(n);++_)
#define _overload4(_1,_2,_3,_4,name,...) name
#define __rep(i,a) repi(i,0,a,1)
#define _rep(i,a,b) repi(i,a,b,1)
#define repi(i,a,b,c) for(long long i=(long long)(a);i<(long long)(b);i+=c)
#define rep(...) _overload4(__VA_ARGS__,repi,_rep,__rep)(__VA_ARGS__)
#define _overload3_rev(_1,_2,_3,name,...) name
#define _rep_rev(i,a) repi_rev(i,0,a)
#define repi_rev(i,a,b) for(long long i=(long long)(b)-1;i>=(long long)(a);--i)
#define rrep(...) _overload3_rev(__VA_ARGS__,repi_rev,_rep_rev)(__VA_ARGS__)

// #define rep(i,...) for(auto i:range(__VA_ARGS__)) 
// #define rrep(i,...) for(auto i:reversed(range(__VA_ARGS__)))
// #define repi(i,a,b) for(lint i=lint(a);i<(lint)(b);++i)
// #define rrepi(i,a,b) for(lint i=lint(b)-1;i>=lint(a);--i)
// #define irep(i) for(lint i=0;;++i)
// inline vector<long long> range(long long n){if(n<=0)return vector<long long>();vector<long long>v(n);iota(v.begin(),v.end(),0LL);return v;}
// inline vector<long long> range(long long a,long long b){if(b<=a)return vector<long long>();vector<long long>v(b-a);iota(v.begin(),v.end(),a);return v;}
// inline vector<long long> range(long long a,long long b,long long c){if((b-a+c-1)/c<=0)return vector<long long>();vector<long long>v((b-a+c-1)/c);for(int i=0;i<(int)v.size();++i)v[i]=i?v[i-1]+c:a;return v;}
// template<typename T>inline T reversed(T v){reverse(v.begin(),v.end());return v;}
#define all(n) begin(n),end(n)
template<typename T,typename E>bool chmin(T& s,const E& t){bool res=s>t;s=min<T>(s,t);return res;}
template<typename T,typename E>bool chmax(T& s,const E& t){bool res=s<t;s=max<T>(s,t);return res;}
// const array<lint,8> dx={1,0,-1,0,1,1,-1,-1};
// const array<lint,8> dy={0,1,0,-1,1,-1,1,-1};
// const string ds="RDLU";
#define SUM(v) accumulate(all(v),0LL)
#if __cplusplus>=201703L
    template<typename T,typename ...Args>auto make_vector(T x,int arg,Args ...args){if constexpr(sizeof...(args)==0)return vector<T>(arg,x);else return vector(arg,make_vector<T>(x,args...));}
#endif
#define extrep(v,...) for(auto v:__MAKE_MAT__({__VA_ARGS__}))
#define bit(n,a) ((n>>a)&1)
vector<vector<long long>> __MAKE_MAT__(vector<long long> v){if(v.empty())return vector<vector<long long>>(1,vector<long long>());long long n=v.back();v.pop_back();vector<vector<long long>> ret;vector<vector<long long>> tmp=__MAKE_MAT__(v);for(auto e:tmp)for(long long i=0;i<n;++i){ret.push_back(e);ret.back().push_back(i);}return ret;}
using graph=vector<vector<int>>;
template<typename T>using graph_w=vector<vector<pair<int,T>>>;

#if __cplusplus>=201703L
    constexpr inline long long powll(long long a,long long b){long long res=1;while(b--)res*=a;return res;}
#endif

template<typename T,typename E>pair<T,E>& operator+=(pair<T,E>&s,const pair<T,E>&t){s.first+=t.first;s.second+=t.second;return s;}
template<typename T,typename E>pair<T,E>& operator-=(pair<T,E>&s,const pair<T,E>&t){s.first-=t.first;s.second-=t.second;return s;}
template<typename T,typename E>pair<T,E> operator+(const pair<T,E>&s,const pair<T,E>&t){auto res=s;return res+=t;}
template<typename T,typename E>pair<T,E> operator-(const pair<T,E>&s,const pair<T,E>&t){auto res=s;return res-=t;}
#define BEGIN_STACK_EXTEND(size) void * stack_extend_memory_ = malloc(size);void * stack_extend_origin_memory_;char * stack_extend_dummy_memory_ = (char*)alloca((1+(int)(((long long)stack_extend_memory_)&127))*16);*stack_extend_dummy_memory_ = 0;asm volatile("mov %%rsp, %%rbx\nmov %%rax, %%rsp":"=b"(stack_extend_origin_memory_):"a"((char*)stack_extend_memory_+(size)-1024));
#define END_STACK_EXTEND asm volatile("mov %%rax, %%rsp"::"a"(stack_extend_origin_memory_));free(stack_extend_memory_);
#line 3 "/home/hotman78/vscode/ICPC/library/cpplib/alga/maybe.hpp"

/**
 * @brief Maybe
 * @see https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%8A%E3%83%89_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)#Maybe%E3%83%A2%E3%83%8A%E3%83%89
 */

template<typename T>
struct maybe{
    bool _is_none;
    T val;
    maybe():_is_none(true){}
    maybe(T val):_is_none(false),val(val){}
    T unwrap()const{
        assert(!_is_none);
        return val;
    }
    T unwrap_or(T e)const{
        return _is_none?e:val;
    }
    bool is_none()const{return _is_none;}
    bool is_some()const{return !_is_none;}
};

template<typename T,typename F>
auto expand(F op){
    return [&op](const maybe<T>& __s,const maybe<T>& __t)->maybe<T>{
        if(__s.is_none())return __t;
        if(__t.is_none())return __s;
        return maybe<T>(op(__s.unwrap(),__t.unwrap()));
    };
}
#line 4 "/home/hotman78/vscode/ICPC/library/cpplib/segment_tree/segment_tree.hpp"

/**
 * @brief セグメント木
 * @see https://en.wikipedia.org/wiki/Segment_tree
 */

template<typename T,typename F>
class segment_tree{
    using i64=long long;
    struct node;
    using np=node*;
    struct node{
        maybe<T>val;
        np ch[2]={nullptr,nullptr};
        node(maybe<T> val=maybe<T>()):val(val){}
    };
    np root=new node();
    i64 n=1;
    i64 sz;
    F op;
	public:
    segment_tree(){}
	segment_tree(i64 sz,F op=F()):sz(sz),op(op){
		while(n<=sz)n<<=1;
	}
    maybe<T> get(i64 a,i64 b){
        return get(a,b,0,n,root);
    }
    void apply(i64 x,T val){
        apply(x,val,0,n,root);
    }
    void apply_left(i64 x,T val){
        apply_left(x,val,0,n,root);
    }
    void change(i64 x,T val){
        change(x,val,0,n,root);
    }
    maybe<T> get(i64 a,i64 b,i64 l,i64 r,np t){
        if(!t)return maybe<T>();
        auto f=expand<T,F>(op);
        if(r<=a||b<=l)return maybe<T>();
        if(a<=l&&r<=b){
            return t->val;
        }
        const i64 m=(l+r)/2;
        return f(get(a,b,l,m,t->ch[0]),get(a,b,m,r,t->ch[1]));
    }
    void apply(i64 x,T val,i64 l,i64 r,np t){
        auto f=expand<T,F>(op);
        if(!t->ch[0])t->ch[0]=new node();
        if(!t->ch[1])t->ch[1]=new node();
        if(l<=x&&x<r){
            t->val=f(t->val,val);
            const i64 m=(l+r)/2;
            if(r-l>1){
                apply(x,val,l,m,t->ch[0]);
                apply(x,val,m,r,t->ch[1]);
            }
        }
    }
    void apply_left(i64 x,T val,i64 l,i64 r,np t){
        if(!t->ch[0])t->ch[0]=new node();
        if(!t->ch[1])t->ch[1]=new node();
        auto f=expand<T,F>(op);
        if(l<=x&&x<r){
            t->val=f(val,t->val);
            i64 m=(l+r)/2;
            if(r-l>1){
                apply_left(x,val,l,m,t->ch[0]);
                apply_left(x,val,m,r,t->ch[1]);
            }
        }
    }
    maybe<T> change(i64 x,const T& val,i64 l,i64 r,np t){
        if(!t->ch[0])t->ch[0]=new node();
        if(!t->ch[1])t->ch[1]=new node();
        auto f=expand<T,F>(op);
        if(l<=x&&x<r){
            if(r-l>1){
                const i64 m=(l+r)/2;
                auto p=change(x,val,l,m,t->ch[0]);
                auto q=change(x,val,m,r,t->ch[1]);
                return t->val=f(p,q);
            }else{
                return t->val=val;
            }
        }
        return t->val;
    }
};
template<typename T>using plus_segment_tree=segment_tree<T,plus<T>>;
template<typename T>
struct MAX_F{
    T operator()(const T& s,const T& t){
        return max(s,t);
    }
};
template<typename T>using max_seg=segment_tree<T,MAX_F<T>>;
#line 3 "main.cpp"

int main(){
    lint m;
    cin>>m;
    string s,t;
    cin>>s>>t;
    set<lint>p,q;
    lint n=300000;
    plus_segment_tree<lint> seg(n);
    q.emplace(n);
    auto flip=[&](set<lint>&s,lint val){
        if(s.count(val))s.erase(s.find(val));
        else s.emplace(val);
    };
    reverse(all(s));
    while((int)s.size()<n)s+='0';
    reverse(all(s));
    reverse(all(t));
    while((int)t.size()<n)t+='0';
    reverse(all(t));

    rep(i,n){
        if(s[i]=='1'){
            seg.apply(i,1);
        }
        if(s[i]=='0'){
            flip(p,i);
        }
        if(t[i]=='1'){
            flip(p,i);
            flip(q,i);
        }
    }

    while(m--){
        string que;
        cin>>que;
        if(que=="Q"){
            lint tmp=*q.begin();
            lint ans=seg.get(0,tmp+1).unwrap_or(0)+(n-tmp-1)+(s[tmp]=='0'&&p.upper_bound(tmp)!=p.end()&&*p.upper_bound(tmp)>=*q.upper_bound(tmp));
            cout<<ans<<endl;
        }else if(que=="A"){
            lint i;
            cin>>i;
            i=n-1-i;
            s[i]=(1-(s[i]-'0'))+'0';
            flip(p,i);
            if(s[i]=='0'){
                seg.change(i,0);
            }else{
                seg.change(i,1);
            }
        }else{
            lint i;
            cin>>i;
            i=n-1-i;
            t[i]=(1-(t[i]-'0'))+'0';
            flip(p,i);
            flip(q,i);
        }
    }
}
accuracy: 0.030303030303030304
time_ms: 80
memory_kb: 17644
final_rank: 19

code_snippet: #line 2 "/home/hotman78/vscode/ICPC/library/cpplib/util/template.hpp"
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("avx2")
#include<bits/stdc++.h>
using namespace std;
#line 1 "/home/hotman78/vscode/ICPC/library/cpplib/util/ioutil.hpp"
// template <class Head,class... Args>
// std::ostream& output(std::ostream& out,const Head& head,const Args&... args){
//     out>>head;
//     return output(head,args...);
// }
// template <class Head>
// std::ostream& output(std::ostream& out,const Head& head){
//     out>>head;
//     return out;
// }

template<typename T,typename E>
std::ostream& operator<<(std::ostream& out,std::pair<T,E>v){
    out<<"("<<v.first<<","<<v.second<<")";return out;
}

// template <class... Args>
// ostream& operator<<(ostream& out,std::tuple<Args...>v){
//     std::apply(output,v);
//     return out;
// }
#line 8 "/home/hotman78/vscode/ICPC/library/cpplib/util/template.hpp"
struct __INIT__{__INIT__(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(15);}}__INIT__;
typedef long long lint;
#define INF (1LL<<60)
#define IINF (1<<30)
#define EPS (1e-10)
#define endl ('\n')
typedef vector<lint> vec;
typedef vector<vector<lint>> mat;
typedef vector<vector<vector<lint>>> mat3;
typedef vector<string> svec;
typedef vector<vector<string>> smat;
template<typename T>using V=vector<T>;
template<typename T>using VV=V<V<T>>;
template<typename T>inline void output(T t){bool f=0;for(auto i:t){cout<<(f?" ":"")<<i;f=1;}cout<<endl;}
template<typename T>inline void output2(T t){for(auto i:t)output(i);}
template<typename T>inline void debug(T t){bool f=0;for(auto i:t){cerr<<(f?" ":"")<<i;f=1;}cerr<<endl;}
template<typename T>inline void debug2(T t){for(auto i:t)debug(i);}
#define loop(n) for(long long _=0;_<(long long)(n);++_)
#define _overload4(_1,_2,_3,_4,name,...) name
#define __rep(i,a) repi(i,0,a,1)
#define _rep(i,a,b) repi(i,a,b,1)
#define repi(i,a,b,c) for(long long i=(long long)(a);i<(long long)(b);i+=c)
#define rep(...) _overload4(__VA_ARGS__,repi,_rep,__rep)(__VA_ARGS__)
#define _overload3_rev(_1,_2,_3,name,...) name
#define _rep_rev(i,a) repi_rev(i,0,a)
#define repi_rev(i,a,b) for(long long i=(long long)(b)-1;i>=(long long)(a);--i)
#define rrep(...) _overload3_rev(__VA_ARGS__,repi_rev,_rep_rev)(__VA_ARGS__)

// #define rep(i,...) for(auto i:range(__VA_ARGS__)) 
// #define rrep(i,...) for(auto i:reversed(range(__VA_ARGS__)))
// #define repi(i,a,b) for(lint i=lint(a);i<(lint)(b);++i)
// #define rrepi(i,a,b) for(lint i=lint(b)-1;i>=lint(a);--i)
// #define irep(i) for(lint i=0;;++i)
// inline vector<long long> range(long long n){if(n<=0)return vector<long long>();vector<long long>v(n);iota(v.begin(),v.end(),0LL);return v;}
// inline vector<long long> range(long long a,long long b){if(b<=a)return vector<long long>();vector<long long>v(b-a);iota(v.begin(),v.end(),a);return v;}
// inline vector<long long> range(long long a,long long b,long long c){if((b-a+c-1)/c<=0)return vector<long long>();vector<long long>v((b-a+c-1)/c);for(int i=0;i<(int)v.size();++i)v[i]=i?v[i-1]+c:a;return v;}
// template<typename T>inline T reversed(T v){reverse(v.begin(),v.end());return v;}
#define all(n) begin(n),end(n)
template<typename T,typename E>bool chmin(T& s,const E& t){bool res=s>t;s=min<T>(s,t);return res;}
template<typename T,typename E>bool chmax(T& s,const E& t){bool res=s<t;s=max<T>(s,t);return res;}
// const array<lint,8> dx={1,0,-1,0,1,1,-1,-1};
// const array<lint,8> dy={0,1,0,-1,1,-1,1,-1};
// const string ds="RDLU";
#define SUM(v) accumulate(all(v),0LL)
#if __cplusplus>=201703L
    template<typename T,typename ...Args>auto make_vector(T x,int arg,Args ...args){if constexpr(sizeof...(args)==0)return vector<T>(arg,x);else return vector(arg,make_vector<T>(x,args...));}
#endif
#define extrep(v,...) for(auto v:__MAKE_MAT__({__VA_ARGS__}))
#define bit(n,a) ((n>>a)&1)
vector<vector<long long>> __MAKE_MAT__(vector<long long> v){if(v.empty())return vector<vector<long long>>(1,vector<long long>());long long n=v.back();v.pop_back();vector<vector<long long>> ret;vector<vector<long long>> tmp=__MAKE_MAT__(v);for(auto e:tmp)for(long long i=0;i<n;++i){ret.push_back(e);ret.back().push_back(i);}return ret;}
using graph=vector<vector<int>>;
template<typename T>using graph_w=vector<vector<pair<int,T>>>;

#if __cplusplus>=201703L
    constexpr inline long long powll(long long a,long long b){long long res=1;while(b--)res*=a;return res;}
#endif

template<typename T,typename E>pair<T,E>& operator+=(pair<T,E>&s,const pair<T,E>&t){s.first+=t.first;s.second+=t.second;return s;}
template<typename T,typename E>pair<T,E>& operator-=(pair<T,E>&s,const pair<T,E>&t){s.first-=t.first;s.second-=t.second;return s;}
template<typename T,typename E>pair<T,E> operator+(const pair<T,E>&s,const pair<T,E>&t){auto res=s;return res+=t;}
template<typename T,typename E>pair<T,E> operator-(const pair<T,E>&s,const pair<T,E>&t){auto res=s;return res-=t;}
#define BEGIN_STACK_EXTEND(size) void * stack_extend_memory_ = malloc(size);void * stack_extend_origin_memory_;char * stack_extend_dummy_memory_ = (char*)alloca((1+(int)(((long long)stack_extend_memory_)&127))*16);*stack_extend_dummy_memory_ = 0;asm volatile("mov %%rsp, %%rbx\nmov %%rax, %%rsp":"=b"(stack_extend_origin_memory_):"a"((char*)stack_extend_memory_+(size)-1024));
#define END_STACK_EXTEND asm volatile("mov %%rax, %%rsp"::"a"(stack_extend_origin_memory_));free(stack_extend_memory_);
#line 3 "/home/hotman78/vscode/ICPC/library/cpplib/alga/maybe.hpp"

/**
 * @brief Maybe
 * @see https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%8A%E3%83%89_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)#Maybe%E3%83%A2%E3%83%8A%E3%83%89
 */

template<typename T>
struct maybe{
    bool _is_none;
    T val;
    maybe():_is_none(true){}
    maybe(T val):_is_none(false),val(val){}
    T unwrap()const{
        assert(!_is_none);
        return val;
    }
    T unwrap_or(T e)const{
        return _is_none?e:val;
    }
    bool is_none()const{return _is_none;}
    bool is_some()const{return !_is_none;}
};

template<typename T,typename F>
auto expand(F op){
    return [&op](const maybe<T>& __s,const maybe<T>& __t)->maybe<T>{
        if(__s.is_none())return __t;
        if(__t.is_none())return __s;
        return maybe<T>(op(__s.unwrap(),__t.unwrap()));
    };
}
#line 4 "/home/hotman78/vscode/ICPC/library/cpplib/segment_tree/segment_tree.hpp"

/**
 * @brief セグメント木
 * @see https://en.wikipedia.org/wiki/Segment_tree
 */

template<typename T,typename F>
class segment_tree{
    using i64=long long;
    struct node;
    using np=node*;
    struct node{
        maybe<T>val;
        np ch[2]={nullptr,nullptr};
        node(maybe<T> val=maybe<T>()):val(val){}
    };
    np root=new node();
    i64 n=1;
    i64 sz;
    F op;
	public:
    segment_tree(){}
	segment_tree(i64 sz,F op=F()):sz(sz),op(op){
		while(n<=sz)n<<=1;
	}
    maybe<T> get(i64 a,i64 b){
        return get(a,b,0,n,root);
    }
    void apply(i64 x,T val){
        apply(x,val,0,n,root);
    }
    void apply_left(i64 x,T val){
        apply_left(x,val,0,n,root);
    }
    void change(i64 x,T val){
        change(x,val,0,n,root);
    }
    maybe<T> get(i64 a,i64 b,i64 l,i64 r,np t){
        if(!t)return maybe<T>();
        auto f=expand<T,F>(op);
        if(r<=a||b<=l)return maybe<T>();
        if(a<=l&&r<=b){
            return t->val;
        }
        const i64 m=(l+r)/2;
        return f(get(a,b,l,m,t->ch[0]),get(a,b,m,r,t->ch[1]));
    }
    void apply(i64 x,T val,i64 l,i64 r,np t){
        auto f=expand<T,F>(op);
        if(!t->ch[0])t->ch[0]=new node();
        if(!t->ch[1])t->ch[1]=new node();
        if(l<=x&&x<r){
            t->val=f(t->val,val);
            const i64 m=(l+r)/2;
            if(r-l>1){
                apply(x,val,l,m,t->ch[0]);
                apply(x,val,m,r,t->ch[1]);
            }
        }
    }
    void apply_left(i64 x,T val,i64 l,i64 r,np t){
        if(!t->ch[0])t->ch[0]=new node();
        if(!t->ch[1])t->ch[1]=new node();
        auto f=expand<T,F>(op);
        if(l<=x&&x<r){
            t->val=f(val,t->val);
            i64 m=(l+r)/2;
            if(r-l>1){
                apply_left(x,val,l,m,t->ch[0]);
                apply_left(x,val,m,r,t->ch[1]);
            }
        }
    }
    maybe<T> change(i64 x,const T& val,i64 l,i64 r,np t){
        if(!t->ch[0])t->ch[0]=new node();
        if(!t->ch[1])t->ch[1]=new node();
        auto f=expand<T,F>(op);
        if(l<=x&&x<r){
            if(r-l>1){
                const i64 m=(l+r)/2;
                auto p=change(x,val,l,m,t->ch[0]);
                auto q=change(x,val,m,r,t->ch[1]);
                return t->val=f(p,q);
            }else{
                return t->val=val;
            }
        }
        return t->val;
    }
};
template<typename T>using plus_segment_tree=segment_tree<T,plus<T>>;
template<typename T>
struct MAX_F{
    T operator()(const T& s,const T& t){
        return max(s,t);
    }
};
template<typename T>using max_seg=segment_tree<T,MAX_F<T>>;
#line 3 "main.cpp"

int main(){
    lint m;
    cin>>m;
    string s,t;
    cin>>s>>t;
    set<lint>p,q;
    lint n=300000;
    plus_segment_tree<lint> seg(n);
    p.emplace(n);
    q.emplace(n+1);
    auto flip=[&](set<lint>&s,lint val){
        if(s.count(val))s.erase(s.find(val));
        else s.emplace(val);
    };
    reverse(all(s));
    while((int)s.size()<n)s+='0';
    reverse(all(s));
    reverse(all(t));
    while((int)t.size()<n)t+='0';
    reverse(all(t));

    rep(i,n){
        if(s[i]=='1'){
            seg.apply(i,1);
        }
        if(s[i]=='0'){
            flip(p,i);
        }
        if(t[i]=='1'){
            flip(q,i);
            q.emplace(i);
        }
    }

    while(m--){
        string que;
        cin>>que;
        if(que=="Q"){
            lint tmp=*q.begin();
            lint ans=seg.get(0,tmp+1).unwrap_or(0)+(n-tmp-1)+(s[tmp]=='0'&&*p.upper_bound(tmp)>=*q.upper_bound(tmp));
            cout<<ans<<endl;
        }else if(que=="A"){
            lint i;
            cin>>i;
            i=n-1-i;
            s[i]=(1-(s[i]-'0'))+'0';
            flip(p,i);
            if(s[i]=='0'){
                seg.change(i,0);
            }else{
                seg.change(i,1);
            }
        }else{
            lint i;
            cin>>i;
            i=n-1-i;
            t[i]=(1-(t[i]-'0'))+'0';
            flip(p,i);
            flip(q,i);
        }
    }
}
accuracy: 0.015151515151515152
time_ms: 80
memory_kb: 17940
final_rank: 20

code_snippet: #include <bits/stdc++.h>

#ifdef _MSC_VER
#  include <intrin.h>
#else
#  include <x86intrin.h>
#endif

#include <limits>
#include <type_traits>

namespace suisen {
// ! utility
template <typename ...Types>
using constraints_t = std::enable_if_t<std::conjunction_v<Types...>, std::nullptr_t>;
template <bool cond_v, typename Then, typename OrElse>
constexpr decltype(auto) constexpr_if(Then&& then, OrElse&& or_else) {
    if constexpr (cond_v) {
        return std::forward<Then>(then);
    } else {
        return std::forward<OrElse>(or_else);
    }
}

// ! function
template <typename ReturnType, typename Callable, typename ...Args>
using is_same_as_invoke_result = std::is_same<std::invoke_result_t<Callable, Args...>, ReturnType>;
template <typename F, typename T>
using is_uni_op = is_same_as_invoke_result<T, F, T>;
template <typename F, typename T>
using is_bin_op = is_same_as_invoke_result<T, F, T, T>;

template <typename Comparator, typename T>
using is_comparator = std::is_same<std::invoke_result_t<Comparator, T, T>, bool>;

// ! integral
template <typename T, typename = constraints_t<std::is_integral<T>>>
constexpr int bit_num = std::numeric_limits<std::make_unsigned_t<T>>::digits;
template <typename T, unsigned int n>
struct is_nbit { static constexpr bool value = bit_num<T> == n; };
template <typename T, unsigned int n>
static constexpr bool is_nbit_v = is_nbit<T, n>::value;

// ?
template <typename T>
struct safely_multipliable {};
template <>
struct safely_multipliable<int> { using type = long long; };
template <>
struct safely_multipliable<long long> { using type = __int128_t; };
template <>
struct safely_multipliable<unsigned int> { using type = unsigned long long; };
template <>
struct safely_multipliable<unsigned long int> { using type = __uint128_t; };
template <>
struct safely_multipliable<unsigned long long> { using type = __uint128_t; };
template <>
struct safely_multipliable<float> { using type = float; };
template <>
struct safely_multipliable<double> { using type = double; };
template <>
struct safely_multipliable<long double> { using type = long double; };
template <typename T>
using safely_multipliable_t = typename safely_multipliable<T>::type;

template <typename T, typename = void>
struct rec_value_type {
    using type = T;
};
template <typename T>
struct rec_value_type<T, std::void_t<typename T::value_type>> {
    using type = typename rec_value_type<typename T::value_type>::type;
};
template <typename T>
using rec_value_type_t = typename rec_value_type<T>::type;

} // namespace suisen

// ! type aliases
using i128 = __int128_t;
using u128 = __uint128_t;

template <typename T>
using pq_greater = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <typename T, typename U>
using umap = std::unordered_map<T, U>;

// ! macros (capital: internal macro)
#define OVERLOAD2(_1,_2,name,...) name
#define OVERLOAD3(_1,_2,_3,name,...) name
#define OVERLOAD4(_1,_2,_3,_4,name,...) name

#define REP4(i,l,r,s)  for(std::remove_reference_t<std::remove_const_t<decltype(r)>>i=(l);i<(r);i+=(s))
#define REP3(i,l,r)    REP4(i,l,r,1)
#define REP2(i,n)      REP3(i,0,n)
#define REPINF3(i,l,s) for(std::remove_reference_t<std::remove_const_t<decltype(l)>>i=(l);;i+=(s))
#define REPINF2(i,l)   REPINF3(i,l,1)
#define REPINF1(i)     REPINF2(i,0)
#define RREP4(i,l,r,s) for(std::remove_reference_t<std::remove_const_t<decltype(r)>>i=(l)+fld((r)-(l)-1,s)*(s);i>=(l);i-=(s))
#define RREP3(i,l,r)   RREP4(i,l,r,1)
#define RREP2(i,n)     RREP3(i,0,n)

#define rep(...)    OVERLOAD4(__VA_ARGS__, REP4   , REP3   , REP2   )(__VA_ARGS__)
#define rrep(...)   OVERLOAD4(__VA_ARGS__, RREP4  , RREP3  , RREP2  )(__VA_ARGS__)
#define repinf(...) OVERLOAD3(__VA_ARGS__, REPINF3, REPINF2, REPINF1)(__VA_ARGS__)

#define CAT_I(a, b) a##b
#define CAT(a, b) CAT_I(a, b)
#define UNIQVAR(tag) CAT(tag, __LINE__)
#define loop(n) for (std::remove_reference_t<std::remove_const_t<decltype(n)>> UNIQVAR(loop_variable) = n; UNIQVAR(loop_variable) --> 0;)

#define all(iterable) std::begin(iterable), std::end(iterable)
#define input(type, ...) type __VA_ARGS__; read(__VA_ARGS__)

#ifdef LOCAL
#  define debug(...) debug_internal(#__VA_ARGS__, __VA_ARGS__)

template <class T, class... Args>
void debug_internal(const char* s, T&& first, Args&&... args) {
    constexpr const char* prefix = "[\033[32mDEBUG\033[m] ";
    constexpr const char* open_brakets = sizeof...(args) == 0 ? "" : "(";
    constexpr const char* close_brakets = sizeof...(args) == 0 ? "" : ")";
    std::cerr << prefix << open_brakets << s << close_brakets << ": " << open_brakets << std::forward<T>(first);
    ((std::cerr << ", " << std::forward<Args>(args)), ...);
    std::cerr << close_brakets << "\n";
}

#else
#  define debug(...) void(0)
#endif

// ! I/O utilities

// __int128_t
std::ostream& operator<<(std::ostream& dest, __int128_t value) {
    std::ostream::sentry s(dest);
    if (s) {
        __uint128_t tmp = value < 0 ? -value : value;
        char buffer[128];
        char* d = std::end(buffer);
        do {
            --d;
            *d = "0123456789"[tmp % 10];
            tmp /= 10;
        } while (tmp != 0);
        if (value < 0) {
            --d;
            *d = '-';
        }
        int len = std::end(buffer) - d;
        if (dest.rdbuf()->sputn(d, len) != len) {
            dest.setstate(std::ios_base::badbit);
        }
    }
    return dest;
}
// __uint128_t
std::ostream& operator<<(std::ostream& dest, __uint128_t value) {
    std::ostream::sentry s(dest);
    if (s) {
        char buffer[128];
        char* d = std::end(buffer);
        do {
            --d;
            *d = "0123456789"[value % 10];
            value /= 10;
        } while (value != 0);
        int len = std::end(buffer) - d;
        if (dest.rdbuf()->sputn(d, len) != len) {
            dest.setstate(std::ios_base::badbit);
        }
    }
    return dest;
}

// pair
template <typename T, typename U>
std::ostream& operator<<(std::ostream& out, const std::pair<T, U>& a) {
    return out << a.first << ' ' << a.second;
}
// tuple
template <unsigned int N = 0, typename ...Args>
std::ostream& operator<<(std::ostream& out, const std::tuple<Args...>& a) {
    if constexpr (N >= std::tuple_size_v<std::tuple<Args...>>) {
        return out;
    } else {
        out << std::get<N>(a);
        if constexpr (N + 1 < std::tuple_size_v<std::tuple<Args...>>) {
            out << ' ';
        }
        return operator<<<N + 1>(out, a);
    }
}
// vector
template <typename T>
std::ostream& operator<<(std::ostream& out, const std::vector<T>& a) {
    for (auto it = a.begin(); it != a.end();) {
        out << *it;
        if (++it != a.end()) out << ' ';
    }
    return out;
}
// array
template <typename T, size_t N>
std::ostream& operator<<(std::ostream& out, const std::array<T, N>& a) {
    for (auto it = a.begin(); it != a.end();) {
        out << *it;
        if (++it != a.end()) out << ' ';
    }
    return out;
}
inline void print() { std::cout << '\n'; }
template <typename Head, typename... Tail>
inline void print(const Head& head, const Tail &...tails) {
    std::cout << head;
    if (sizeof...(tails)) std::cout << ' ';
    print(tails...);
}
template <typename Iterable>
auto print_all(const Iterable& v, std::string sep = " ", std::string end = "\n") -> decltype(std::cout << *v.begin(), void()) {
    for (auto it = v.begin(); it != v.end();) {
        std::cout << *it;
        if (++it != v.end()) std::cout << sep;
    }
    std::cout << end;
}

__int128_t parse_i128(std::string& s) {
    __int128_t ret = 0;
    for (int i = 0; i < int(s.size()); i++) if ('0' <= s[i] and s[i] <= '9') ret = 10 * ret + s[i] - '0';
    if (s[0] == '-') ret = -ret;
    return ret;
}
__uint128_t parse_u128(std::string& s) {
    __uint128_t ret = 0;
    for (int i = 0; i < int(s.size()); i++) if ('0' <= s[i] and s[i] <= '9') ret = 10 * ret + s[i] - '0';
    return ret;
}
// __int128_t
std::istream& operator>>(std::istream& in, __int128_t& v) {
    std::string s;
    in >> s;
    v = parse_i128(s);
    return in;
}
// __uint128_t
std::istream& operator>>(std::istream& in, __uint128_t& v) {
    std::string s;
    in >> s;
    v = parse_u128(s);
    return in;
}
// pair
template <typename T, typename U>
std::istream& operator>>(std::istream& in, std::pair<T, U>& a) {
    return in >> a.first >> a.second;
}
// tuple
template <unsigned int N = 0, typename ...Args>
std::istream& operator>>(std::istream& in, std::tuple<Args...>& a) {
    if constexpr (N >= std::tuple_size_v<std::tuple<Args...>>) {
        return in;
    } else {
        return operator>><N + 1>(in >> std::get<N>(a), a);
    }
}
// vector
template <typename T>
std::istream& operator>>(std::istream& in, std::vector<T>& a) {
    for (auto it = a.begin(); it != a.end(); ++it) in >> *it;
    return in;
}
// array
template <typename T, size_t N>
std::istream& operator>>(std::istream& in, std::array<T, N>& a) {
    for (auto it = a.begin(); it != a.end(); ++it) in >> *it;
    return in;
}
template <typename ...Args>
void read(Args &...args) {
    (std::cin >> ... >> args);
}

// ! integral utilities

// Returns pow(-1, n)
template <typename T>
constexpr inline int pow_m1(T n) {
    return -(n & 1) | 1;
}
// Returns pow(-1, n)
template <>
constexpr inline int pow_m1<bool>(bool n) {
    return -int(n) | 1;
}

// Returns floor(x / y)
template <typename T>
constexpr inline T fld(const T x, const T y) {
    return (x ^ y) >= 0 ? x / y : (x - (y + pow_m1(y >= 0))) / y;
}
template <typename T>
constexpr inline T cld(const T x, const T y) {
    return (x ^ y) <= 0 ? x / y : (x + (y + pow_m1(y >= 0))) / y;
}

template <typename T, suisen::constraints_t<suisen::is_nbit<T, 16>> = nullptr>
__attribute__((target("popcnt"))) constexpr inline int popcount(const T x) { return _mm_popcnt_u32(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
__attribute__((target("popcnt"))) constexpr inline int popcount(const T x) { return _mm_popcnt_u32(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
__attribute__((target("popcnt"))) constexpr inline int popcount(const T x) { return _mm_popcnt_u64(x); }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 16>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clz(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clz(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int count_lz(const T x) { return x ? __builtin_clzll(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 16>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctz(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 32>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctz(x) : suisen::bit_num<T>; }
template <typename T, suisen::constraints_t<suisen::is_nbit<T, 64>> = nullptr>
constexpr inline int count_tz(const T x) { return x ? __builtin_ctzll(x) : suisen::bit_num<T>; }
template <typename T>
constexpr inline int floor_log2(const T x) { return suisen::bit_num<T> -1 - count_lz(x); }
template <typename T>
constexpr inline int ceil_log2(const T x) { return floor_log2(x) + ((x & -x) != x); }
template <typename T>
constexpr inline int kth_bit(const T x, const unsigned int k) { return (x >> k) & 1; }
template <typename T>
constexpr inline int parity(const T x) { return popcount(x) & 1; }

// ! container

template <typename T, typename Comparator, suisen::constraints_t<suisen::is_comparator<Comparator, T>> = nullptr>
auto priqueue_comp(const Comparator comparator) {
    return std::priority_queue<T, std::vector<T>, Comparator>(comparator);
}

template <typename Iterable>
auto isize(const Iterable& iterable) -> decltype(int(iterable.size())) {
    return iterable.size();
}

template <typename T, typename Gen, suisen::constraints_t<suisen::is_same_as_invoke_result<T, Gen, int>> = nullptr>
auto generate_vector(int n, Gen generator) {
    std::vector<T> v(n);
    for (int i = 0; i < n; ++i) v[i] = generator(i);
    return v;
}
template <typename T>
auto generate_range_vector(T l, T r) {
    return generate_vector(r - l, [l](int i) { return l + i; });
}
template <typename T>
auto generate_range_vector(T n) {
    return generate_range_vector(0, n);
}

template <typename T>
void sort_unique_erase(std::vector<T>& a) {
    std::sort(a.begin(), a.end());
    a.erase(std::unique(a.begin(), a.end()), a.end());
}

template <typename InputIterator, typename BiConsumer>
auto foreach_adjacent_values(InputIterator first, InputIterator last, BiConsumer f) -> decltype(f(*first++, *last), void()) {
    if (first != last) for (auto itr = first, itl = itr++; itr != last; itl = itr++) f(*itl, *itr);
}
template <typename Container, typename BiConsumer>
auto foreach_adjacent_values(Container c, BiConsumer f) -> decltype(c.begin(), c.end(), void()) {
    foreach_adjacent_values(c.begin(), c.end(), f);
}

// ! other utilities

// x <- min(x, y). returns true iff `x` has chenged.
template <typename T>
inline bool chmin(T& x, const T& y) {
    if (y >= x) return false;
    x = y;
    return true;
}
// x <- max(x, y). returns true iff `x` has chenged.
template <typename T>
inline bool chmax(T& x, const T& y) {
    if (y <= x) return false;
    x = y;
    return true;
}

template <typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
std::string bin(T val, int bit_num = -1) {
    std::string res;
    if (bit_num >= 0) {
        for (int bit = bit_num; bit-- > 0;) res += '0' + ((val >> bit) & 1);
    } else {
        for (; val; val >>= 1) res += '0' + (val & 1);
        std::reverse(res.begin(), res.end());
    }
    return res;
}

template <typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
std::vector<T> digits_low_to_high(T val, T base = 10) {
    std::vector<T> res;
    for (; val; val /= base) res.push_back(val % base);
    if (res.empty()) res.push_back(T{ 0 });
    return res;
}
template <typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
std::vector<T> digits_high_to_low(T val, T base = 10) {
    auto res = digits_low_to_high(val, base);
    std::reverse(res.begin(), res.end());
    return res;
}

template <typename T>
std::string join(const std::vector<T>& v, const std::string& sep, const std::string& end) {
    std::ostringstream ss;
    for (auto it = v.begin(); it != v.end();) {
        ss << *it;
        if (++it != v.end()) ss << sep;
    }
    ss << end;
    return ss.str();
}

namespace suisen {}
using namespace suisen;
using namespace std;

struct io_setup {
    io_setup(int precision = 20) {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout << std::fixed << std::setprecision(precision);
    }
} io_setup_{};

// ! code from here

#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n)) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
constexpr int bsf_constexpr(unsigned int n) {
    int x = 0;
    while (!(n & (1 << x))) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

}  // namespace internal

}  // namespace atcoder

namespace atcoder {

template <class S,
          S (*op)(S, S),
          S (*e)(),
          class F,
          S (*mapping)(F, S),
          F (*composition)(F, F),
          F (*id)()>
struct lazy_segtree {
  public:
    lazy_segtree() : lazy_segtree(0) {}
    explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
    explicit lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
        log = internal::ceil_pow2(_n);
        size = 1 << log;
        d = std::vector<S>(2 * size, e());
        lz = std::vector<F>(size, id());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        return d[p];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return e();

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        S sml = e(), smr = e();
        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }

        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    void apply(int p, F f) {
        assert(0 <= p && p < _n);
        p += size;
        for (int i = log; i >= 1; i--) push(p >> i);
        d[p] = mapping(f, d[p]);
        for (int i = 1; i <= log; i++) update(p >> i);
    }
    void apply(int l, int r, F f) {
        assert(0 <= l && l <= r && r <= _n);
        if (l == r) return;

        l += size;
        r += size;

        for (int i = log; i >= 1; i--) {
            if (((l >> i) << i) != l) push(l >> i);
            if (((r >> i) << i) != r) push((r - 1) >> i);
        }

        {
            int l2 = l, r2 = r;
            while (l < r) {
                if (l & 1) all_apply(l++, f);
                if (r & 1) all_apply(--r, f);
                l >>= 1;
                r >>= 1;
            }
            l = l2;
            r = r2;
        }

        for (int i = 1; i <= log; i++) {
            if (((l >> i) << i) != l) update(l >> i);
            if (((r >> i) << i) != r) update((r - 1) >> i);
        }
    }

    template <bool (*g)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return g(x); });
    }
    template <class G> int max_right(int l, G g) {
        assert(0 <= l && l <= _n);
        assert(g(e()));
        if (l == _n) return _n;
        l += size;
        for (int i = log; i >= 1; i--) push(l >> i);
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!g(op(sm, d[l]))) {
                while (l < size) {
                    push(l);
                    l = (2 * l);
                    if (g(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*g)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return g(x); });
    }
    template <class G> int min_left(int r, G g) {
        assert(0 <= r && r <= _n);
        assert(g(e()));
        if (r == 0) return 0;
        r += size;
        for (int i = log; i >= 1; i--) push((r - 1) >> i);
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!g(op(d[r], sm))) {
                while (r < size) {
                    push(r);
                    r = (2 * r + 1);
                    if (g(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;
    std::vector<F> lz;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    void all_apply(int k, F f) {
        d[k] = mapping(f, d[k]);
        if (k < size) lz[k] = composition(f, lz[k]);
    }
    void push(int k) {
        all_apply(2 * k, lz[k]);
        all_apply(2 * k + 1, lz[k]);
        lz[k] = id();
    }
};

}  // namespace atcoder

pair<int, int> op(pair<int, int> x, pair<int, int> y) {
    return { x.first + y.first, x.second + y.second };
}
pair<int, int> e() {
    return { 0, 0 };
}
pair<int, int> mapping(int8_t f, pair<int, int> x) {
    if (not f) return x;
    return { x.second - x.first, x.second };
}
int8_t composition(int8_t f, int8_t g) {
    return f ^ g;
}
int8_t id() {
    return false;
}

int main() {
    input(int, n);
    vector<int> a, b;

    {
        input(string, sa);
        for (char c : sa) {
            a.push_back(c - '0');
        }
        input(string, sb);
        for (char c : sb) {
            b.push_back(c - '0');
        }
        reverse(all(a));
        reverse(all(b));
    }

    const int l = max(a.size(), b.size());
    a.resize(l + 1);
    b.resize(l + 1);
    vector<int> c(l + 1);
    {
        int carry = 0;
        rep(i, l) {
            c[i] = a[i] ^ b[i] ^ carry;
            carry = a[i] + b[i] + carry >= 2;
        }
        c[l] = carry;
        rep(i, l + 1) {
            if (c[i] == 0) {
                c[i] = 1;
            } else {
                c[i] = 0;
                break;
            }
        }
    }

    vector<int> x(l + 1);
    rep(i, l + 1) {
        x[i] = a[i] ^ c[i];
    }

    auto make_segtree = [&](const vector<int>& v) {
        vector<pair<int, int>> init(l + 1);
        rep(i, l + 1) {
            init[i] = { v[i], 1 };
        }
        return atcoder::lazy_segtree<pair<int, int>, op, e, int8_t, mapping, composition, id>(init);
    };

    // auto sa = make_segtree(a);
    auto sc = make_segtree(c);
    auto sx = make_segtree(x);

    loop(n) {
        input(char, op);
        if (op == 'Q') {
            int m = sx.min_left(l + 1, [&](const pair<int, int>& v) { return v.first == 0; });
            int r = sc.prod(m, l + 1).first;
            debug(m, r);
            print(m + r - (sc.prod(0, m).first != m));
            continue;
        }

        input(int, i);
        if (op == 'A') {
            if (a[i] == 0) {
                int j = sc.max_right(i, [&](const pair<int, int>& v) { return v.first == v.second; });
                sc.apply(i, j + 1, 1);
                sx.apply(i + 1, j + 1, 1);
            } else {
                int j = sc.max_right(i, [&](const pair<int, int>& v) { return v.first == 0; });
                sc.apply(i, j + 1, 1);
                sx.apply(i + 1, j + 1, 1);
            }
            a[i] ^= 1;
        } else {
            if (b[i] == 0) {
                int j = sc.max_right(i, [&](const pair<int, int>& v) { return v.first == v.second; });
                sc.apply(i, j + 1, 1);
                sx.apply(i, j + 1, 1);
            } else {
                int j = sc.max_right(i, [&](const pair<int, int>& v) { return v.first == 0; });
                sc.apply(i, j + 1, 1);
                sx.apply(i, j + 1, 1);
            }
            b[i] ^= 1;
        }
    }

    return 0;
}
accuracy: 1
time_ms: 140
memory_kb: 27444
final_rank: 5

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define eps 1e-9
#define INF 2000000000              // 2e9
#define LLINF 2000000000000000000ll // 2e18 (llmax:9e18)
#define all(x) (x).begin(), (x).end()
#define sq(x) ((x) * (x))

#define rep(i, x) for (int i = 0; i < (int)(x); i++)
#define drep(i, x) for (int i = ((int)(x)-1); i >= 0; i--)

#define popcount __builtin_popcount
#define next __next
#define prev __prev

#ifndef LOCAL
#define dmp(...) ;
#else
#define dmp(...)                                                               \
  cerr << "[ " << #__VA_ARGS__ << " ] : " << dump_str(__VA_ARGS__) << endl
#endif

// ---------------- Utility ------------------

template <class T>
bool chmin(T &a, const T &b) {
  if (a <= b) return false;
  a = b;
  return true;
}

template <class T>
bool chmax(T &a, const T &b) {
  if (a >= b) return false;
  a = b;
  return true;
}

template <class T>
using MaxHeap = priority_queue<T>;

template <class T>
using MinHeap = priority_queue<T, vector<T>, greater<T>>;

template <class T>
vector<T> vect(int len, T elem) {
  return vector<T>(len, elem);
}

// ----------------- Input -------------------

template <class T, class U>
istream &operator>>(istream &is, pair<T, U> &p) {
  return is >> p.first >> p.second;
}

template <class T>
istream &operator>>(istream &is, vector<T> &vec) {
  for (int i = 0; i < vec.size(); i++) is >> vec[i];
  return is;
}

// ----------------- Output ------------------

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << p.first << ',' << p.second;
}

template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (const T &e : v) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const deque<T> &d) {
  for (const T &e : d) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const set<T> &s) {
  os << "{ ";
  for (const T &e : s) os << e << " ";
  return os << "}";
}

template <class T, class U>
ostream &operator<<(ostream &os, const map<T, U> &m) {
  os << "{ ";
  for (const auto &[key, val] : m) os << "( " << key << " -> " << val << " ) ";
  return os << "}";
}

template <class TupleTy, size_t... I>
void dump_tuple(ostream &os, const TupleTy t, std::index_sequence<I...>) {
  (..., (os << (I == 0 ? "" : ",") << std::get<I>(t)));
}

template <class... Args>
ostream &operator<<(ostream &os, const tuple<Args...> &t) {
  os << "(";
  dump_tuple(os, t, std::make_index_sequence<sizeof...(Args)>());
  return os << ")";
}

void dump_str_rec(ostringstream &) {}

template <class Head, class... Tail>
void dump_str_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << ", " << head;
  dump_str_rec(oss, forward<Tail>(tail)...);
}

template <class T, class... U>
string dump_str(T &&arg, U &&... args) {
  ostringstream oss;
  oss << arg;
  dump_str_rec(oss, forward<U>(args)...);
  return oss.str();
}

// --------------- Fast I/O ------------------

void fastio() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cout << fixed << setprecision(20);
}

// ------------------ ACL --------------------

// #include <atcoder/modint>
// constexpr int MOD = 998244353;
// constexpr int MOD = 1000000007;
// using mint = atcoder::static_modint<MOD>;
// ostream &operator<<(ostream &os, const mint &v) {
//   return os << v.val();
// }

// ------------ End of template --------------

#define endl "\n"
using ll = long long;
using pii = pair<int, int>;

const bool multitest = false;

using S = int;
S op(S a, S b) {
  return a + b;
}
S e() {
  return 0;
}


#include <algorithm>
#include <cassert>
#include <vector>


#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n)) x++;
    return x;
}

int bsf(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

}  // namespace internal

}  // namespace atcoder


namespace atcoder {

template <class S, S (*op)(S, S), S (*e)()> struct segtree {
  public:
    segtree() : segtree(0) {}
    explicit segtree(int n) : segtree(std::vector<S>(n, e())) {}
    explicit segtree(const std::vector<S>& v) : _n(int(v.size())) {
        log = internal::ceil_pow2(_n);
        size = 1 << log;
        d = std::vector<S>(2 * size, e());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) const {
        assert(0 <= p && p < _n);
        return d[p + size];
    }

    S prod(int l, int r) const {
        assert(0 <= l && l <= r && r <= _n);
        S sml = e(), smr = e();
        l += size;
        r += size;

        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }

    S all_prod() const { return d[1]; }

    template <bool (*f)(S)> int max_right(int l) const {
        return max_right(l, [](S x) { return f(x); });
    }
    template <class F> int max_right(int l, F f) const {
        assert(0 <= l && l <= _n);
        assert(f(e()));
        if (l == _n) return _n;
        l += size;
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(op(sm, d[l]))) {
                while (l < size) {
                    l = (2 * l);
                    if (f(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*f)(S)> int min_left(int r) const {
        return min_left(r, [](S x) { return f(x); });
    }
    template <class F> int min_left(int r, F f) const {
        assert(0 <= r && r <= _n);
        assert(f(e()));
        if (r == 0) return 0;
        r += size;
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(op(d[r], sm))) {
                while (r < size) {
                    r = (2 * r + 1);
                    if (f(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};

}  // namespace atcoder


void solve() {
  int N;
  string a, b;
  cin >> N;
  cin >> a >> b;
  reverse(all(a));
  reverse(all(b));
  int M = max(a.size(), b.size()) + 1;
  while (a.size() < M) a += '0';
  while (b.size() < M) b += '0';

  atcoder::segtree<S, op, e> A(M), B(M), Or(M), And(M);
  for (int i = 0; i < M; i++) {
    int c = a[i] - '0', d = b[i] - '0';
    A.set(i, c);
    B.set(i, d);
    Or.set(i, c | d);
    And.set(i, c & d);
  }

  for (int q = 0; q < N; q++) {
    char type;
    cin >> type;
    if (type == 'Q') {
      int bsum = B.all_prod();
      int msb = B.max_right(0, [&](int x) { return x < bsum; });
      dmp(msb);
      assert(B.get(msb) == 1);
      int cand = A.prod(msb + 1, M) + msb + 1;
      if (A.get(msb) == 1) {
        cout << cand << endl;
      } else {
        int max_and = And.min_left(msb, [](int x) { return x == 0; }) - 1;
        if (max_and >= 0) {
          if (Or.prod(max_and + 1, msb) == (msb - max_and - 1)) {
            cout << cand << endl;
          } else {
            cout << cand - 1 << endl;
          }
        } else {
          cout << cand - 1 << endl;
        }
      }
    } else if (type == 'A') {
      int k;
      cin >> k;
      int c = A.get(k), d = B.get(k);
      c ^= 1;
      A.set(k, c);
      B.set(k, d);
      Or.set(k, c | d);
      And.set(k, c & d);

    } else {
      int k;
      cin >> k;
      int c = A.get(k), d = B.get(k);
      d ^= 1;
      A.set(k, c);
      B.set(k, d);
      Or.set(k, c | d);
      And.set(k, c & d);
    }
  }
  return;
}

int main() {
  fastio();
  if (!multitest) {
    solve();
  } else {
    cerr << "[Warning] Multi testcase mode on" << endl;
    int t;
    cin >> t;
    while (t--) solve();
  }
  return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 21144
final_rank: 1

code_snippet: #pragma GCC tag("avx2")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll,ll> P;
typedef pair<int,int> pii;
typedef vector<P> vpl;
typedef tuple<ll,ll,ll> tapu;
#define rep(i,n) for(int i=0; i<(n); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T> inline void print(T &a){
    int sz = a.size();
    for(auto itr = a.begin(); itr != a.end(); itr++){
		cout << *itr;
        sz--;
        if(sz) cout << " ";
	}
    cout << "\n";
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){
	cout << a << " " << b << "\n";
}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << "\n";
}
void mark() {cout << "#" << "\n";}
ll pcount(ll x) {return __builtin_popcountll(x);}
//#include <atcoder/maxflow>
//using namespace atcoder;
const int inf = (1<<30)-1;
const ll linf = 1LL<<61;
const int MAX = 5050000;
int dy[8] = {0,1,0,-1,1,-1,-1,1};
int dx[8] = {-1,0,1,0,1,-1,1,-1};
const double pi = acos(-1);
const double eps = 1e-9;
const int mod = 1e9 + 7;
//const int mod = 998244353;

template<typename T> struct BIT{
    vector<T> dat;
    ll sz;
    //all 1-indexed
    BIT(ll sz) : sz(sz){
        dat.assign(++sz, 0);
    }

    T sum(ll k){
        T ret = 0;
        for(++k; k > 0; k -= k & -k) ret += dat[k];
        return (ret);
    }

    void add(ll k, T x){
        for(++k; k < dat.size(); k += k & -k) dat[k] += x;
    }
    
    ll get(T k){
        if(k <= 0) return 0; 
        ll ret = 0;
        int n = 1; while(n < sz) n *= 2;
        for(int i=n/2; i>0; i/=2){
            if(ret+i < sz && dat[ret+i] < k){
                k -= dat[ret+i];
                ret += i;
            }
        }
        return ret;
    }
};

int main(){
    int q; cin >> q;
    string a,b; cin >> a >> b;
    reverse(all(a)); reverse(all(b));
    int sa = a.size(), sb = b.size();
    while(sa < sb) a.push_back('0'), sa++;
    while(sb < sa) b.push_back('0'), sb++;
    BIT<int> bit(sa+1);
    rep(i,sa) bit.add(i,a[i]-'0');
    set<int> B,a0b0,a1b1;
    rep(i,sb){
        if(b[i] == '1') B.insert(i);
        if(a[i] == '0' && b[i] == '0'){
            a0b0.insert(i);
        }
        if(a[i] == '1' && b[i] == '1'){
            a1b1.insert(i);
        }
    }
    B.insert(-1); a0b0.insert(-1); a1b1.insert(-1);
    while(q--){
        char c; cin >> c;
        if(c == 'Q'){
            int msb = *--B.end();
            int one = *--a1b1.upper_bound(msb);
            int zero = *--a0b0.upper_bound(msb);
            int ans = bit.sum(sa) - bit.sum(msb);
            //debug(msb,one,zero,ans);
            if(one > zero) ans += msb+1;
            else ans += msb;
            cout << ans << "\n";
            continue;
        }
        int k; cin >> k;
        if(c == 'A'){
            if(a[k] == '1'){
                bit.add(k,-1);
                if(b[k] == '1') a1b1.erase(k);
                else a0b0.insert(k);
            }else{
                bit.add(k,1);
                if(b[k] == '1') a1b1.insert(k);
                else a0b0.erase(k);
            }
            a[k] = '1' - a[k] + '0';
        }else{
            if(b[k] == '1'){
                B.erase(k);
                if(a[k] == '1') a1b1.erase(k);
                else a0b0.insert(k);
            }else{
                B.insert(k);
                if(a[k] == '1') a1b1.insert(k);
                else a0b0.erase(k);
            }
            b[k] = '1' - b[k] + '0';
        }
    }
}
accuracy: 1
time_ms: 310
memory_kb: 18936
final_rank: 4

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
#include<deque>
#include<iomanip>
#include<tuple>
#include<cassert>
#include<set>
#include<complex>
#include<numeric>
#include<functional>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long int LL;
typedef pair<int,int> P;
typedef pair<LL,LL> LP;
const int INF=1<<30;
const LL MAX=1e9+7;

void array_show(int *array,int array_n,char middle=' '){
	for(int i=0;i<array_n;i++)printf("%d%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(LL *array,int array_n,char middle=' '){
	for(int i=0;i<array_n;i++)printf("%lld%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(vector<int> &vec_s,int vec_n=-1,char middle=' '){
	if(vec_n==-1)vec_n=vec_s.size();
	for(int i=0;i<vec_n;i++)printf("%d%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
void array_show(vector<LL> &vec_s,int vec_n=-1,char middle=' '){
	if(vec_n==-1)vec_n=vec_s.size();
	for(int i=0;i<vec_n;i++)printf("%lld%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
template<typename T> ostream& operator<<(ostream& os,const vector<T>& v1){
	int n=v1.size();
	for(int i=0;i<n;i++){
		if(i)os<<" ";
		os<<v1[i];
	}
	return os;
}
template<typename T1,typename T2> ostream& operator<<(ostream& os,const pair<T1,T2>& p){
	os<<p.first<<" "<<p.second;
	return os;
}
template<typename T> istream& operator>>(istream& is,vector<T>& v1){
	int n=v1.size();
	for(int i=0;i<n;i++)is>>v1[i];
	return is;
}
template<typename T1,typename T2> istream& operator>>(istream& is,pair<T1,T2>& p){
	is>>p.first>>p.second;
	return is;
}

template<typename T> class bit{
private:
	vector<T> bit_vec;
	int bit_N=20;

	T bit_comp(T a,T b){
		return a+b;
	}

public:

	bit(int n){
		for(bit_N=0;bit_N<30;bit_N++){
			if(n<(1<<bit_N))break;
		}
		bit_vec.assign((1<<bit_N),0);
	}

	void set(int pos,T x){
		bit_vec[pos]=bit_comp(bit_vec[pos],x);
		for(int i=0;i<bit_N;i++){
			if(pos&(1<<i))continue;
			pos|=(1<<i);
			bit_vec[pos]=bit_comp(bit_vec[pos],x);
		}
	}

	T search(int pos){
		T s=bit_vec[pos];
		for(int i=0;pos>=(1<<i);i++){
			if(pos&(1<<i))continue;
			pos-=(1<<i);
			s=bit_comp(s,bit_vec[pos]);
		}
		return s;
	}
};

namespace sol{
	const int N=3e5+7;
	vector<int> va,vb,vc(N,-1);
	vector<set<int>> ss(3);
	set<int> s1;
	bit<int> bt(N);

	vector<int> str2vec(string sa){
		vector<int> vs(N);
		int dif=N-sa.size();
		for(int i=0;i<sa.size();i++){
			vs[dif+i]=sa[i]-'0';
		}
		return vs;
	}

	void setbit(int pos){
		if(vc[pos]!=-1)ss[vc[pos]].erase(pos);
		vc[pos]=va[pos]+vb[pos];
		ss[vc[pos]].insert(pos);
	}

	void solve(){
		int n,m;
		int i,j,k;
		int a,b,c;
		string sa,sb;
		char ca;
		cin>>n>>sa>>sb;
		va=str2vec(sa);
		vb=str2vec(sb);
		for(i=0;i<N;i++){
			setbit(i);
			bt.set(i,va[i]);
			if(vb[i]==1)s1.insert(i);
		}
		ss[0].insert(N);
		ss[2].insert(N);
		for(i=0;i<n;i++){
			cin>>ca;
			if(ca=='A'){
				cin>>a;
				a=N-a-1;
				va[a]^=1;
				setbit(a);
				if(va[a]==1)bt.set(a,1);
				else bt.set(a,-1);
				continue;
			}
			if(ca=='B'){
				cin>>a;
				a=N-a-1;
				vb[a]^=1;
				setbit(a);
				if(vb[a]==1)s1.insert(a);
				else s1.erase(a);
				continue;
			}
			a=*(s1.lower_bound(0));
			b=*(ss[0].lower_bound(a));
			c=*(ss[2].lower_bound(a));
			if(b>c){
				auto itr=ss[0].lower_bound(a);
				assert(itr!=ss[0].begin());
				itr--;
				a=*itr;
			}
			int s=bt.search(a)+N-a-1;
			cout<<s<<endl;
		}
	}
}

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	sol::solve();
}
accuracy: 1
time_ms: 340
memory_kb: 30248
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=1000000007,MAX=205,INF=1<<29;

// BIT セグ木 遅延セグ木 のみ

// from: https://gist.github.com/yosupo06/ddd51afb727600fd95d9d8ad6c3c80c9
// (based on AtCoder STL)

#include <algorithm>
#include <array>
#ifdef _MSC_VER
#include <intrin.h>
#endif
namespace atcoder {
    namespace internal {
        int ceil_pow2(int n) {
            int x = 0;
            while ((1U << x) < (unsigned int)(n)) x++;
            return x;
        }
        int bsf(unsigned int n) {
#ifdef _MSC_VER
            unsigned long index;
            _BitScanForward(&index, n);
            return index;
#else
            return __builtin_ctz(n);
#endif
        }
    }  // namespace internal
    
}  // namespace atcoder

#include <cassert>
#include <numeric>
#include <type_traits>

namespace atcoder {
    
    namespace internal {
        
#ifndef _MSC_VER
        template <class T>
        using is_signed_int128 =
        typename std::conditional<std::is_same<T, __int128_t>::value ||
        std::is_same<T, __int128>::value,
        std::true_type,
        std::false_type>::type;
        
        template <class T>
        using is_unsigned_int128 =
        typename std::conditional<std::is_same<T, __uint128_t>::value ||
        std::is_same<T, unsigned __int128>::value,
        std::true_type,
        std::false_type>::type;
        
        template <class T>
        using make_unsigned_int128 =
        typename std::conditional<std::is_same<T, __int128_t>::value,
        __uint128_t,
        unsigned __int128>;
        
        template <class T>
        using is_integral = typename std::conditional<std::is_integral<T>::value ||
        is_signed_int128<T>::value ||
        is_unsigned_int128<T>::value,
        std::true_type,
        std::false_type>::type;
        
        template <class T>
        using is_signed_int = typename std::conditional<(is_integral<T>::value &&
                                                         std::is_signed<T>::value) ||
        is_signed_int128<T>::value,
        std::true_type,
        std::false_type>::type;
        
        template <class T>
        using is_unsigned_int =
        typename std::conditional<(is_integral<T>::value &&
                                   std::is_unsigned<T>::value) ||
        is_unsigned_int128<T>::value,
        std::true_type,
        std::false_type>::type;
        
        template <class T>
        using to_unsigned = typename std::conditional<
        is_signed_int128<T>::value,
        make_unsigned_int128<T>,
        typename std::conditional<std::is_signed<T>::value,
        std::make_unsigned<T>,
        std::common_type<T>>::type>::type;
        
#else
        
        template <class T> using is_integral = typename std::is_integral<T>;
        
        template <class T>
        using is_signed_int =
        typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
        std::true_type,
        std::false_type>::type;
        
        template <class T>
        using is_unsigned_int =
        typename std::conditional<is_integral<T>::value &&
        std::is_unsigned<T>::value,
        std::true_type,
        std::false_type>::type;
        
        template <class T>
        using to_unsigned = typename std::conditional<is_signed_int<T>::value,
        std::make_unsigned<T>,
        std::common_type<T>>::type;
        
#endif
        
        template <class T>
        using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;
        
        template <class T>
        using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;
        
        template <class T> using to_unsigned_t = typename to_unsigned<T>::type;
        
    }  // namespace internal
    
}  // namespace atcoder

#include <cassert>
#include <vector>

namespace atcoder {
    
    template <class T> struct fenwick_tree {
        using U = internal::to_unsigned_t<T>;
        
    public:
        fenwick_tree() : _n(0) {}
        fenwick_tree(int n) : _n(n), data(n) {}
        
        void add(int p, T x) {
            assert(0 <= p && p < _n);
            p++;
            while (p <= _n) {
                data[p - 1] += U(x);
                p += p & -p;
            }
        }
        
        T sum(int l, int r) {
            assert(0 <= l && l <= r && r <= _n);
            return sum(r) - sum(l);
        }
        
    private:
        int _n;
        std::vector<U> data;
        
        U sum(int r) {
            U s = 0;
            while (r > 0) {
                s += data[r - 1];
                r -= r & -r;
            }
            return s;
        }
    };
    
}  // namespace atcoder


#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
namespace atcoder {
    
    template <class S,
    S (*op)(S, S),
    S (*e)(),
    class F,
    S (*mapping)(F, S),
    F (*composition)(F, F),
    F (*id)()>
    struct lazy_segtree {
    public:
        lazy_segtree() : lazy_segtree(0) {}
        lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {}
        lazy_segtree(const std::vector<S>& v) : _n(int(v.size())) {
            log = internal::ceil_pow2(_n);
            size = 1 << log;
            d = std::vector<S>(2 * size, e());
            lz = std::vector<F>(size, id());
            for (int i = 0; i < _n; i++) d[size + i] = v[i];
            for (int i = size - 1; i >= 1; i--) {
                update(i);
            }
        }
        
        void set(int p, S x) {
            assert(0 <= p && p < _n);
            p += size;
            for (int i = log; i >= 1; i--) push(p >> i);
            d[p] = x;
            for (int i = 1; i <= log; i++) update(p >> i);
        }
        
        S get(int p) {
            assert(0 <= p && p < _n);
            p += size;
            for (int i = log; i >= 1; i--) push(p >> i);
            return d[p];
        }
        
        S prod(int l, int r) {
            assert(0 <= l && l <= r && r <= _n);
            if (l == r) return e();
            
            l += size;
            r += size;
            
            for (int i = log; i >= 1; i--) {
                if (((l >> i) << i) != l) push(l >> i);
                if (((r >> i) << i) != r) push(r >> i);
            }
            
            S sml = e(), smr = e();
            while (l < r) {
                if (l & 1) sml = op(sml, d[l++]);
                if (r & 1) smr = op(d[--r], smr);
                l >>= 1;
                r >>= 1;
            }
            
            return op(sml, smr);
        }
        
        S all_prod() { return d[1]; }
        
        void apply(int p, F f) {
            assert(0 <= p && p < _n);
            p += size;
            for (int i = log; i >= 1; i--) push(p >> i);
            d[p] = mapping(f, d[p]);
            for (int i = 1; i <= log; i++) update(p >> i);
        }
        void apply(int l, int r, F f) {
            assert(0 <= l && l <= r && r <= _n);
            if (l == r) return;
            
            l += size;
            r += size;
            
            for (int i = log; i >= 1; i--) {
                if (((l >> i) << i) != l) push(l >> i);
                if (((r >> i) << i) != r) push((r - 1) >> i);
            }
            
            {
                int l2 = l, r2 = r;
                while (l < r) {
                    if (l & 1) all_apply(l++, f);
                    if (r & 1) all_apply(--r, f);
                    l >>= 1;
                    r >>= 1;
                }
                l = l2;
                r = r2;
            }
            
            for (int i = 1; i <= log; i++) {
                if (((l >> i) << i) != l) update(l >> i);
                if (((r >> i) << i) != r) update((r - 1) >> i);
            }
        }
        
        template <bool (*g)(S)> int max_right(int l) {
            return max_right(l, [](S x) { return g(x); });
        }
        template <class G> int max_right(int l, G g) {
            assert(0 <= l && l <= _n);
            assert(g(e()));
            if (l == _n) return _n;
            l += size;
            for (int i = log; i >= 1; i--) push(l >> i);
            S sm = e();
            do {
                while (l % 2 == 0) l >>= 1;
                if (!g(op(sm, d[l]))) {
                    while (l < size) {
                        push(l);
                        l = (2 * l);
                        if (g(op(sm, d[l]))) {
                            sm = op(sm, d[l]);
                            l++;
                        }
                    }
                    return l - size;
                }
                sm = op(sm, d[l]);
                l++;
            } while ((l & -l) != l);
            return _n;
        }
        
        template <bool (*g)(S)> int min_left(int r) {
            return min_left(r, [](S x) { return g(x); });
        }
        template <class G> int min_left(int r, G g) {
            assert(0 <= r && r <= _n);
            assert(g(e()));
            if (r == 0) return 0;
            r += size;
            for (int i = log; i >= 1; i--) push((r - 1) >> i);
            S sm = e();
            do {
                r--;
                while (r > 1 && (r % 2)) r >>= 1;
                if (!g(op(d[r], sm))) {
                    while (r < size) {
                        push(r);
                        r = (2 * r + 1);
                        if (g(op(d[r], sm))) {
                            sm = op(d[r], sm);
                            r--;
                        }
                    }
                    return r + 1 - size;
                }
                sm = op(d[r], sm);
            } while ((r & -r) != r);
            return 0;
        }
        
    private:
        int _n, size, log;
        std::vector<S> d;
        std::vector<F> lz;
        
        void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
        void all_apply(int k, F f) {
            d[k] = mapping(f, d[k]);
            if (k < size) lz[k] = composition(f, lz[k]);
        }
        void push(int k) {
            all_apply(2 * k, lz[k]);
            all_apply(2 * k + 1, lz[k]);
            lz[k] = id();
        }
    };
    
}  // namespace atcoder

#include <algorithm>
#include <cassert>
#include <vector>

namespace atcoder {
    
    template <class S, S (*op)(S, S), S (*e)()> struct segtree {
    public:
        segtree() : segtree(0) {}
        segtree(int n) : segtree(std::vector<S>(n, e())) {}
        segtree(const std::vector<S>& v) : _n(int(v.size())) {
            log = internal::ceil_pow2(_n);
            size = 1 << log;
            d = std::vector<S>(2 * size, e());
            for (int i = 0; i < _n; i++) d[size + i] = v[i];
            for (int i = size - 1; i >= 1; i--) {
                update(i);
            }
        }
        
        void set(int p, S x) {
            assert(0 <= p && p < _n);
            p += size;
            d[p] = x;
            for (int i = 1; i <= log; i++) update(p >> i);
        }
        
        S get(int p) {
            assert(0 <= p && p < _n);
            return d[p + size];
        }
        
        S prod(int l, int r) {
            assert(0 <= l && l <= r && r <= _n);
            S sml = e(), smr = e();
            l += size;
            r += size;
            
            while (l < r) {
                if (l & 1) sml = op(sml, d[l++]);
                if (r & 1) smr = op(d[--r], smr);
                l >>= 1;
                r >>= 1;
            }
            return op(sml, smr);
        }
        
        S all_prod() { return d[1]; }
        
        template <bool (*f)(S)> int max_right(int l) {
            return max_right(l, [](S x) { return f(x); });
        }
        template <class F> int max_right(int l, F f) {
            assert(0 <= l && l <= _n);
            assert(f(e()));
            if (l == _n) return _n;
            l += size;
            S sm = e();
            do {
                while (l % 2 == 0) l >>= 1;
                if (!f(op(sm, d[l]))) {
                    while (l < size) {
                        l = (2 * l);
                        if (f(op(sm, d[l]))) {
                            sm = op(sm, d[l]);
                            l++;
                        }
                    }
                    return l - size;
                }
                sm = op(sm, d[l]);
                l++;
            } while ((l & -l) != l);
            return _n;
        }
        
        template <bool (*f)(S)> int min_left(int r) {
            return min_left(r, [](S x) { return f(x); });
        }
        template <class F> int min_left(int r, F f) {
            assert(0 <= r && r <= _n);
            assert(f(e()));
            if (r == 0) return 0;
            r += size;
            S sm = e();
            do {
                r--;
                while (r > 1 && (r % 2)) r >>= 1;
                if (!f(op(d[r], sm))) {
                    while (r < size) {
                        r = (2 * r + 1);
                        if (f(op(d[r], sm))) {
                            sm = op(d[r], sm);
                            r--;
                        }
                    }
                    return r + 1 - size;
                }
                sm = op(d[r], sm);
            } while ((r & -r) != r);
            return 0;
        }
        
    private:
        int _n, size, log;
        std::vector<S> d;
        
        void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
    };
    
}  // namespace atcoder

using T=pair<ll,int>;
using E=ll;

T f(T a,T b){
    return mp(a.fi+b.fi,a.se+b.se);
}

T g(E a,T b){
    if(a==INF) return b;
    return mp(a*b.se,b.se);
}

E h(E a,E b){
    if(a==INF) return b;
    return a;
}

T ti(){
    return mp(0LL,1);
}

E ei(){
    return INF;
}

struct TT{
    ll dat;
    ll sum;
};

using EE=bool;

TT f(TT a,TT b){
    return {a.dat^b.dat,a.sum^b.sum};
}

TT g(EE a,TT b){
    if(!a) return b;
    return {b.dat,b.sum^b.dat};
}

EE h(EE a,EE b){
    return a^b;
}

TT titi(){
    return {0,0};
}

EE eiei(){
    return false;
}

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    
    int Q;cin>>Q;
    string A,B;cin>>A>>B;
    int M=max(si(A)+1,si(B)+1);
    reverse(all(A));
    while(si(A)<M) A+='0';
    reverse(all(A));
    
    reverse(all(B));
    while(si(B)<M) B+='0';
    reverse(all(B));
    
    vector<int> C(M);
    for(int i=M-1;i>=0;i--){
        C[i]+=int(A[i]-'0')+int(B[i]-'0');
        if(C[i]>=2){
            C[i]-=2;
            C[i-1]++;
        }
    }
    
    vector<T> defa(M,mp(0,1)),defc(M,mp(0,1));
    vector<TT> deha(M),dehc(M);
    for(int i=0;i<M;i++){
        ll x=rng();
        x=abs(x);
        deha[i].dat=dehc[i].dat=x;
        if(A[i]=='1'){
            defa[i].fi=1;
            deha[i].sum=x;
        }
        if(C[i]){
            defc[i].fi=1;
            dehc[i].sum=x;
        }
    }
    atcoder::lazy_segtree<T,f,ti,E,g,h,ei> sega(defa),segc(defc);
    atcoder::lazy_segtree<TT,f,titi,EE,g,h,eiei> hasa(deha),hasc(dehc);
    
    while(Q--){
        char c;cin>>c;
        if(c=='Q'){
            int left=0,right=M;
            while(right-left>1){
                int mid=(left+right)/2;
                if(hasa.prod(0,mid).sum!=hasc.prod(0,mid).sum) right=mid;
                else left=mid;
            }
            int res=0;
            res+=segc.prod(0,left).fi;
            res+=M-right;
            cout<<res<<"\n";
        }else{
            int p;cin>>p;p=M-1-p;
            if(c=='B'){
                if(segc.get(p).fi==0){
                    if(B[p]=='0'){
                        segc.apply(p,1);
                        hasc.apply(p,1);
                    }else{
                        int left=0,right=p+1;
                        while(right-left>1){
                            int mid=(left+right)/2;
                            if(segc.prod(0,mid).fi==segc.prod(0,p+1).fi) right=mid;
                            else left=mid;
                        }
                        segc.apply(left,0);
                        segc.apply(right,p+1,1);
                        hasc.apply(left,p+1,1);
                    }
                }else{
                    if(B[p]=='0'){
                        int left=0,right=p+1;
                        while(right-left>1){
                            int mid=(left+right)/2;
                            if(segc.prod(0,mid).fi-mid==segc.prod(0,p+1).fi-(p+1)) right=mid;
                            else left=mid;
                        }
                        segc.apply(left,1);
                        segc.apply(right,p+1,0);
                        hasc.apply(left,p+1,1);
                    }else{
                        segc.apply(p,0);
                        hasc.apply(p,1);
                    }
                }
                B[p]=char('0'+(int(B[p]-'0')^1));
            }else{
                if(segc.get(p).fi==0){
                    if(A[p]=='0'){
                        segc.apply(p,1);
                        hasc.apply(p,1);
                    }else{
                        int left=0,right=p+1;
                        while(right-left>1){
                            int mid=(left+right)/2;
                            if(segc.prod(0,mid).fi==segc.prod(0,p+1).fi) right=mid;
                            else left=mid;
                        }
                        segc.apply(left,0);
                        segc.apply(right,p+1,1);
                        hasc.apply(left,p+1,1);
                    }
                }else{
                    if(A[p]=='0'){
                        int left=0,right=p+1;
                        while(right-left>1){
                            int mid=(left+right)/2;
                            if(segc.prod(0,mid).fi-mid==segc.prod(0,p+1).fi-(p+1)) right=mid;
                            else left=mid;
                        }
                        segc.apply(left,1);
                        segc.apply(right,p+1,0);
                        hasc.apply(left,p+1,1);
                    }else{
                        segc.apply(p,0);
                        hasc.apply(p,1);
                    }
                }
                
                if(sega.get(p).fi==0){
                    if(A[p]=='0'){
                        sega.apply(p,1);
                        hasa.apply(p,1);
                    }else{
                        int left=0,right=p+1;
                        while(right-left>1){
                            int mid=(left+right)/2;
                            if(sega.prod(0,mid).fi==sega.prod(0,p+1).fi) right=mid;
                            else left=mid;
                        }
                        sega.apply(left,0);
                        sega.apply(right,p+1,1);
                        hasa.apply(left,p+1,1);
                    }
                }else{
                    if(A[p]=='0'){
                        int left=0,right=p+1;
                        while(right-left>1){
                            int mid=(left+right)/2;
                            if(sega.prod(0,mid).fi-mid==sega.prod(0,p+1).fi-(p+1)) right=mid;
                            else left=mid;
                        }
                        sega.apply(left,1);
                        sega.apply(right,p+1,0);
                        hasa.apply(left,p+1,1);
                    }else{
                        sega.apply(p,0);
                        hasa.apply(p,1);
                    }
                }
                
                A[p]=char('0'+(int(A[p]-'0')^1));
            }
        }
    }
}
accuracy: 1
time_ms: 1410
memory_kb: 97504
final_rank: 18

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += m;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n % mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 22;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[a - b];
}

struct BIT {
private:
	vector<ll> node; int n;
public:
	BIT(int n_) {
		n = n_; node.resize(n, 0);
	}
	//0-indexed
	void add(int a, ll w) {
		for (int i = a; i < n; i |= i + 1)node[i] += w;
	}
	//[0,a)
	ll sum(int a) {
		ll ret = 0;
		for (int i = a - 1; i >= 0; i = (i & (i + 1)) - 1)ret += node[i];
		return ret;
	}
	//[a,b)
	ll sum(int a, int b) {
		return sum(b) - sum(a);
	}
};


void solve() {
	int q; cin >> q;
	string a, b; cin >> a >> b;
	reverse(all(a));
	reverse(all(b));
	int n = max(a.size(), b.size());
	a.resize(n, '0');
	b.resize(n, '0');
	set<int> st;
	st.insert(-1);
	rep(i, n)if (a[i] == b[i])st.insert(i);
	BIT bt(n);
	rep(i, n)if (a[i] == '0')bt.add(i, 1);
	set<int> stb;
	rep(i, n)if (b[i] == '1')stb.insert(i);

	//!!!update st,stb,bt!!!
	rep(i, q) {
		char c; cin >> c;
		if (c == 'Q') {
			int ans = n - bt.sum(0, n);
			if (stb.size()) {
				int f = *--stb.end();
				if (a[f] == '0') {
					st.insert(f);
					auto itr = st.find(f);
					itr--;
					st.erase(f);
					int d = *itr;
					if (d <0||a[d] == '0') {
						ans += bt.sum(0, f);
					}
					else {
						ans += bt.sum(0, f) + 1;
						//cout << "hello\n";
					}
				}
				else {
					ans += bt.sum(0, f);
				}
			}
			cout << ans << "\n";
		}
		else if (c == 'A') {
			int loc; cin >> loc;
			if (a[loc] == '1') {
				bt.add(loc, 1);
			}
			else {
				bt.add(loc, -1);
			}
			if (a[loc] == b[loc]) {
				st.erase(loc);
			}
			else {
				st.insert(loc);
			}
			a[loc] = '1' + '0' - a[loc];
		}
		else if (c == 'B') {
			int loc; cin >> loc;
			if (a[loc] == b[loc]) {
				st.erase(loc);
			}
			else {
				st.insert(loc);
			}
			if (b[loc] == '1') {
				stb.erase(loc);
			}
			else {
				stb.insert(loc);
			}
			b[loc] = '1' + '0' - b[loc];
		}
	}
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(10);
	//init_f();
	//init();
	//expr();
	//int t; cin >> t; rep(i, t)
		//expr();
	//while(cin>>n,n)
	solve();
	return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 85740
final_rank: 15

code_snippet: #include <bits/stdc++.h>

#include <algorithm>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n)) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

}  // namespace internal

}  // namespace atcoder

#include <cassert>
#include <vector>

namespace atcoder {

template <class S, S (*op)(S, S), S (*e)()> struct segtree {
  public:
    segtree() : segtree(0) {}
    segtree(int n) : segtree(std::vector<S>(n, e())) {}
    segtree(const std::vector<S>& v) : _n(int(v.size())) {
        log = internal::ceil_pow2(_n);
        size = 1 << log;
        d = std::vector<S>(2 * size, e());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        return d[p + size];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        S sml = e(), smr = e();
        l += size;
        r += size;

        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    template <bool (*f)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return f(x); });
    }
    template <class F> int max_right(int l, F f) {
        assert(0 <= l && l <= _n);
        assert(f(e()));
        if (l == _n) return _n;
        l += size;
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(op(sm, d[l]))) {
                while (l < size) {
                    l = (2 * l);
                    if (f(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*f)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return f(x); });
    }
    template <class F> int min_left(int r, F f) {
        assert(0 <= r && r <= _n);
        assert(f(e()));
        if (r == 0) return 0;
        r += size;
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(op(d[r], sm))) {
                while (r < size) {
                    r = (2 * r + 1);
                    if (f(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};

}  // namespace atcoder

using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;
template<class T>
inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return true;
    }
    return false;
}

template<class T>
inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return true;
    }
    return false;
}

const long long INF = 1e18;
//const ll mod = 1000000007;
ll N, A[2][310000];
struct S {
    ll num[2][2];
};
S op(S a, S b) {
    S ret;
    for(int i = 0; i < 2; i++) {
        for(int j = 0; j < 2; j++) {
            ret.num[i][j] = a.num[i][j] + b.num[i][j];
        }
    }
    return ret;
}
S e() {
    S ret;
    for(int i = 0; i < 2; i++) {
        for(int j = 0; j < 2; j++) {
            ret.num[i][j] = 0;
        }
    }
    return ret;
}

using segtree = atcoder::segtree<S, op, e>;

bool ALLONE(S x) {
    return x.num[1][1] <= 0;
}
bool ALLZERO(S x) {
    return x.num[0][0] <= 0;
}
bool BONE(S x) {
    return x.num[0][1] + x.num[1][1] <= 0;
}

void print(segtree seg) {
    for(int i = 0; i < N; i++) {
        auto tmp = seg.prod(i, i + 1);
        for(int j = 0; j < 2; j++) {
            for(int k = 0; k < 2; k++) {
                cerr << tmp.num[j][k] << " ";
            }
        }
        cerr << endl;
    }
}
string T[2];

int main() {
    ll Q;
    cin >> Q;
    cin >> T[0] >> T[1];
    N = max(T[0].size(), T[1].size());
    for(int i = 0; i < 2; i++) {
        T[i] = string(N - T[i].size(), '0') + T[i];
    }
    for(int i = 0; i < 2; i++) {
        string S = T[i];
        for(int j = 0; j < N; j++) {
            A[i][j] = (int)(S[j] - '0');
        }
    }
    vector<S> v(N, e());
    for(int i = 0; i < N; i++) {
        v[i].num[A[0][i]][A[1][i]]++;
    }
    segtree seg(v);
    for(int q = 0; q < Q; q++) {
        //print(seg);
        /*
        for(int i = 0; i < 2; i++) {
            for(int j = 0; j < N; j++) {
                cerr << A[i][j];
            }
            cerr << endl;
        }
        */
        char type;
        cin >> type;
        if(type == 'A') {
            ll idx;
            cin >> idx;
            idx = N - 1 - idx;
            A[0][idx] = 1 - A[0][idx];
            auto tmp = e();
            tmp.num[A[0][idx]][A[1][idx]]++;
            seg.set(idx, tmp);
        }
        if(type == 'B') {
            ll idx;
            cin >> idx;
            idx = N - 1 - idx;
            A[1][idx] = 1 - A[1][idx];
            auto tmp = e();
            tmp.num[A[0][idx]][A[1][idx]]++;
            seg.set(idx, tmp);
        }
        if(type == 'Q') {
            ll mini = seg.max_right<BONE>(0);
            ll zero = N;
            if(mini < N) zero = seg.max_right<ALLZERO>(mini);
            ll one = N;
            if(mini < N) one = seg.max_right<ALLONE>(mini);
            auto tmp = e();
            if(mini >= 1) tmp = seg.prod(0, mini);
            ll ans = tmp.num[1][0];
            ans += (N - mini - 1);
            //cerr << mini << " " << ans << " " << zero << " " << one << endl;
            if(one < N and zero > one) {
                ans++;
            }
            cout << ans << endl;
        }
    }
    return 0;
}
accuracy: 1
time_ms: 240
memory_kb: 50796
final_rank: 10

code_snippet: #define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <string.h>

#define SWAP(_a,_b) ((_a)^=(_b)^=(_a)^=(_b))

char A[300007], B[300007], op,lastOP,sum[300007];
int a[300007], b[3000007];
int la, lb, lmax, N, opIndex, ans;

void Init()
{
    int i;
    scanf("%d%s%s", &N,&A,&B);
    getchar();
    la = strlen(A);
    lb = strlen(B);

    for (i = 0; i < la; ++i)a[la - 1 - i] = A[i] - '0';
    for (i = 0; i < lb; ++i)b[lb - 1 - i] = B[i] - '0';

    lmax = la > lb ? la + 1 : lb + 1;
}

void AddOne(int _index)
{
    sum[_index]++;
    if (sum[_index] >= 2)
    {
        while (_index < lmax)
        {
            sum[_index + 1]++;
            sum[_index] -= 2;
            if (sum[_index + 1] == 1)break;
            _index++;
        }
    }
}


void LowOne(int _index)
{
    sum[_index]--;
    if (sum[_index] < 0)
    {
        while (_index < lmax)
        {
            sum[_index + 1]--;
            sum[_index] += 2;
            if (sum[_index + 1] == 0)break;
            _index++;
        }
    }
}

int main()
{
    //freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
    Init();
    int i;
    for (i = 0; i < lmax; ++i)
    {
        sum[i] += a[i] + b[i];
        if (sum[i] >= 2) {
            sum[i] -= 2;
            sum[i + 1]++;
        }
    }
    while (N--)
    {
        scanf("%c", &op);
        //printf("op(%c)\n", op);
        if(op== 'Q')
        {
            getchar();
            if (lastOP == 'Q')
            {
                printf("%d\n", ans);
                continue;
            }
            ans = 0;
            //for (i = 0; i < lmax; ++i)sum[i] = 0;
            
            for (i = lmax; i >=0; --i)
            {
                if (a[i] != sum[i])
                {
                    //printf("ans:%d i:%d\n",ans, i);
                    ans += i;
                    break;
                }
                if (a[i]==1)ans++;
            }
            printf("%d\n", ans);
        }
        else if (op == 'A')
        {
            scanf("%d", &opIndex);
            getchar();
            a[opIndex] ? LowOne(opIndex) : AddOne(opIndex);
            a[opIndex] = !a[opIndex];
        }
        else if (op == 'B')
        {
            scanf("%d", &opIndex);
            getchar();
            b[opIndex] ? LowOne(opIndex) : AddOne(opIndex);
            b[opIndex] = !b[opIndex];
        }
        lastOP = op;
    }
    return 0;
}
accuracy: 1
time_ms: 2040
memory_kb: 5920
final_rank: 16

code_snippet: #include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "numeric"
#include "cassert"
#include "ctime"

using namespace std;

constexpr long long int MOD = 1000000007;
//constexpr int MOD = 1000000007;
//constexpr int MOD = 998244353;
//constexpr long long int MOD = 998244353;
constexpr double EPS = 1e-9;

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


int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin >> K;
	string s, t;
	cin >> s >> t;
	N = max(s.size(), t.size());
	N++;
	reverse(s.begin(), s.end());
	reverse(t.begin(), t.end());
	M = sqrt(N) + 1;
	while (s.size() < M*M)s.push_back('0');
	while (t.size() < M*M)t.push_back('0');
	for (auto &i : s)i -= '0';
	for (auto &i : t)i -= '0';
	vector<vector<int>>v(M, vector<int>(2));
	vector<vector<int>>one(M, vector<int>(2, -1));
	vector<vector<int>>sum(M, vector<int>(2));
	for (int i = 0; i < M; i++) {
		for (int j = 0; j < 2; j++) {
			int nx = j;
			for (int k = 0; k < M; k++) {
				int idx = i * M + k;
				nx = nx + s[idx] + t[idx];
				if (nx == 1 && s[idx] == 0) {
					one[i][j] = idx;
				}
				sum[i][j] += nx & 1;
				nx >>= 1;
			}
			v[i][j] = nx;
		}
	}
	while (K--) {
		char a;
		cin >> a;
		if (a == 'Q') {
			int ans = 0;
			int nx = 0;
			int p = -1;
			for (int i = 0; i < M; i++) {
				ans += sum[i][nx];
				p = max(p, one[i][nx]);
				nx = v[i][nx];
			}
			int cn = 0;
			nx = 0;
			int minus = 0;
			while (p / M != cn / M) {
				minus += sum[cn / M][nx];
				nx = v[cn / M][nx];
				cn += M;
			}
			while (p >= cn) {
				nx = nx + s[cn] + t[cn];
				minus += nx & 1;
				nx >>= 1;
				cn++;
			}
			cout << ans+p-minus << endl;
			continue;
		}
		cin >> N;
		if (a == 'A') {
			s[N] ^= 1;
		}
		else {
			t[N] ^= 1;
		}
		int st = N / M;
		for (int i = 0; i < 2; i++) {
			int nx = i;
			one[st][i] = -1;
			sum[st][i] = 0;
			for (int j = 0; j < M; j++) {
				int idx = st * M + j;
				nx = nx + s[idx] + t[idx];
				if (nx == 1 && s[idx] == 0) {
					one[st][i] = idx;
				}
				sum[st][i] += nx & 1;
				nx >>= 1;
			}
			v[st][i] = nx;
		}
		
	}
}
accuracy: 1
time_ms: 1810
memory_kb: 3960
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcountll

#define INF 1e16
#define mod 1000000007

struct BIT{
  int n;
  vector<ll> bit;
  BIT(int size):n(size),bit(size+1,0){}

  ll sum(int i){
    if(i==-1)return 0;
    i++;
    ll s=0;
    while(i>0){
      s+=bit[i];
      i-=i&-i;
    }
    return s;
  }

  void add(int i,ll v){
    i++;
    while(i<=n){
      bit[i]+=v;
      i+=i&-i;
    }
  }

  ll lower_bound(ll w){
    if(w<=0)return 0;
    ll x=0,r=1;
    while(r<n)r<<=1;
    for(ll k=r;k>0;k>>=1){
      if(x+k<=n&&bit[x+k]<w){
        w-=bit[x+k];
        x+=k;
      }
    }
    return x;
  }
};

int Q,N=300010;
string A,B;
set<int> id0,id1;

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);

  cin>>Q>>A>>B;
  reverse(all(A)); reverse(all(B));
  BIT bita(N),bitb(N);
  int totb=0;

  rep(i,A.size()){
    if(A[i]=='1')bita.add(i,1);
  }
  rep(i,B.size()){
    if(B[i]=='1'){
      bitb.add(i,1);
      totb++;
    }
  }
  rep(i,N){
    if(bita.sum(i)-bita.sum(i-1)==0&&bitb.sum(i)-bitb.sum(i-1)==0)id0.insert(-i);
    if(bita.sum(i)-bita.sum(i-1)==1&&bitb.sum(i)-bitb.sum(i-1)==1)id1.insert(-i);
  }

  while(Q--){
    char typ;
    cin>>typ;
    if(typ=='Q'){
      int r=bitb.lower_bound(totb);

      int idx0=-100000000,idx1=-100000000;
      if(id0.size()){
        auto it=id0.lower_bound(-r);
        idx0=-(*it);
      }

      if(id1.size()){
        auto it=id1.lower_bound(-r);
        idx1=-(*it);
      }

      if(idx1>idx0){
        cout<<bita.sum(N-1)-bita.sum(r)+r+1<<endl;
      }else{
        cout<<bita.sum(N-1)-bita.sum(r)+r<<endl;
      }
    }else{
      int i;
      cin>>i;
      int crta=bita.sum(i)-bita.sum(i-1);
      int crtb=bitb.sum(i)-bitb.sum(i-1);
      if(typ=='A'){
        if(crta==0){
          bita.add(i,1);
          if(crtb==0)id0.erase(-i);
          else id1.insert(-i);
        }else{
          bita.add(i,-1);
          if(crtb==1)id1.erase(-i);
          else id0.insert(-i);
        }
      }else{
        if(crtb==0){
          bitb.add(i,1);
          totb++;
          if(crta==0)id0.erase(-i);
          else id1.insert(-i);
        }else{
          bitb.add(i,-1);
          totb--;
          if(crta==1)id1.erase(-i);
          else id0.insert(-i);
        }
      }
    }
  }

  return 0;
}
accuracy: 1
time_ms: 350
memory_kb: 22100
final_rank: 7

code_snippet: #include <bits/stdc++.h>
#define INF 1<<19
using namespace std;
typedef long long ll;
typedef pair<int,int> P;

class segtree{
public:
	static const int N=1<<19;
	int dp[1<<20];
	int cnt[1<<20];
	segtree(){
		for(int i=0;i<N*2;i++){
			dp[i]=INF;
			cnt[i]=0;
		}
	}
	void update(int k,int v){
		k+=N-1;
		dp[k]=v;
		if(v==INF){
			cnt[k]=0;
		}else{
			cnt[k]=1;
		}
		while(k>0){
			k=(k-1)/2;
			dp[k]=min(dp[k*2+1],dp[k*2+2]);
			cnt[k]=cnt[k*2+1]+cnt[k*2+2];
		}
	}

	int query(int a,int b,int k=0,int l=0,int r=N){
		if(b<=l || r<=a)return INF;
		if(a<=l && r<=b)return dp[k];
		int mid=(l+r)/2;
		int vl=query(a,b,k*2+1,l,mid);
		int vr=query(a,b,k*2+2,mid,r);
		return min(vl,vr);
	}

	int query2(int a,int b,int k=0,int l=0,int r=N){
		if(b<=l || r<=a)return 0;
		if(a<=l && r<=b)return cnt[k];
		int mid=(l+r)/2;
		int vl=query2(a,b,k*2+1,l,mid);
		int vr=query2(a,b,k*2+2,mid,r);
		return vl+vr;
	}
};

segtree seg[4];
int bit[300005];

int main(void){
	int q;
	string a,b;
	cin >> q >> a >> b;
	int n2=a.size();
	int m2=b.size();
	for(int i=0;i<n2;i++){
		if(a[i]=='1'){
			bit[i+max(0,m2-n2)]^=1;
		}
	}
	for(int i=0;i<m2;i++){
		if(b[i]=='1'){
			bit[i+max(0,n2-m2)]^=2;
		}
	}
	int n=max(n2,m2);
	for(int i=0;i<n;i++){
		seg[bit[i]].update(i,i);
	}
	for(int i=0;i<q;i++){
		char c;
		scanf(" %c",&c);
		if(c=='Q'){
			int pos[4];
			for(int j=0;j<4;j++){
				pos[j]=seg[j].dp[0];
			}
			if(min(pos[1],pos[2])>pos[3]){
				printf("%d\n",n-pos[3]);
			}else if(pos[1]<pos[2]){
				if(seg[0].query(pos[1],n)>seg[3].query(pos[1],n)){
					printf("%d\n",n-pos[1]);
				}else if(seg[2].query(pos[1],n)>seg[3].query(pos[1],n)){
					int v=seg[3].query(pos[1],n);
					printf("%d\n",n-v+seg[1].query2(0,v));
				}else{
					int v=seg[2].query(pos[1],n);
					if(seg[0].query(v,n)>seg[3].query(v,n)){
						printf("%d\n",n-min(v,n)+seg[1].query2(0,v));
					}else{
						printf("%d\n",max(n-min(v,n)+seg[1].query2(0,v)-1,0));
					}
				}
			}else{
				if(seg[0].query(pos[2],n)>seg[3].query(pos[2],n)){
					printf("%d\n",n-pos[2]);
				}else{
					printf("%d\n",n-pos[2]-1);
				}
			}
		}else{
			int a;
			scanf("%d",&a);
			a=n-a-1;
			seg[bit[a]].update(a,INF);
			if(c=='A'){
				bit[a]^=1;
			}else{
				bit[a]^=2;
			}
			seg[bit[a]].update(a,a);
		}
	}
	return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 37476
final_rank: 8

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 1000005

int N;
int BIT[NUM];
int A[NUM],B[NUM];
int len_A,len_B,len_max;
char buf_A[NUM],buf_B[NUM];
bool table[NUM];
set<int> B_POS,COMMON_POS;

void add(int loc,int value){

	BIT[loc] += value;

	loc += loc & -loc;

	while(loc <= N){
		BIT[loc] += value;
		loc += loc & -loc;
	}
}

int getSum(int loc){

	int sum = BIT[loc];

	loc -= loc & -loc;

	while(loc > 0){
		sum += BIT[loc];
		loc -= loc & -loc;
	}
	return sum;
}


int calc(int left,int right){
	return getSum(right)-getSum(left-1);
}

void init(int first_N){
	while(N < first_N)N *= 2;
}

void update(int loc){
	loc += N-1;

	table[loc] = (A[loc-(N-1)-1] == 1 || B[loc-(N-1)-1]);

	if(N == 1)return;

	int parent = (loc-1)/2;

	while(true){
		table[parent] = table[2*parent+1] && table[2*parent+2];

		if(parent == 0)break;
		else{
			parent = (parent-1)/2;
		}
	}
}

bool is_all_1(int search_left,int search_right,int node_id,int node_left,int node_right){

	if(search_right < node_left || search_left > node_right){
		return true;
	}

	if(search_left <= node_left && search_right >= node_right){
		return table[node_id];
	}

	bool is_left = is_all_1(search_left,search_right,2*node_id+1,node_left,(node_left+node_right)/2);
	bool is_right = is_all_1(search_left,search_right,2*node_id+2,(node_left+node_right)/2+1,node_right);

	return is_left && is_right;
}

int get_index(int loc){

	return loc+1;
}


int main(){

	int num_query;
	scanf("%d %s %s",&num_query,buf_A,buf_B);

	for(len_A = 0; buf_A[len_A] != '\0'; len_A++);
	for(len_B = 0; buf_B[len_B] != '\0'; len_B++);

	len_max = max(len_A,len_B);

	for(int i = 0; i < len_max; i++){
		A[i] = 0;
		B[i] = 0;
	}

	for(int i = len_A-1; i >= 0; i--){
		A[(len_A-1)-i] = buf_A[i]-'0';
	}
	for(int i = len_B-1; i >= 0; i--){
		B[(len_B-1)-i] = buf_B[i]-'0';
		if(B[(len_B-1)-i] == 1){
			B_POS.insert(get_index((len_B-1)-i));
			if(A[(len_B-1)-i] == 1){
				COMMON_POS.insert(get_index((len_B-1)-i));
			}
		}
	}

	N = 1;
	init(len_max+1);

	for(int i = 0; i <= 2*N-2; i++)table[i] = false;
	for(int i = 0; i <= len_max; i++)BIT[i] = 0;

	for(int i = 0; i < len_max; i++){
		add(get_index(i),A[i]);
		update(get_index(i));
	}

	char command[2];
	int tmp_loc,B_head_loc,tmp,COMMON_head_loc;

	for(int loop = 0; loop < num_query; loop++){

		scanf("%s",command);

		switch(command[0]){
		case 'A':
			scanf("%d",&tmp_loc);

			if(A[tmp_loc] == 0){

				A[tmp_loc] = 1;
				add(get_index(tmp_loc),1);
				if(B[tmp_loc] == 1){
					COMMON_POS.insert(get_index(tmp_loc));
				}

			}else{ //A[tmp_loc] == 1

				A[tmp_loc] = 0;
				add(get_index(tmp_loc),-1);
				COMMON_POS.erase(get_index(tmp_loc));

			}
			update(get_index(tmp_loc));

			break;
		case 'B':
			scanf("%d",&tmp_loc);

			if(B[tmp_loc] == 0){

				B[tmp_loc] = 1;
				B_POS.insert(get_index(tmp_loc));
				if(A[tmp_loc] == 1){
					COMMON_POS.insert(get_index(tmp_loc));
				}

			}else{ //B[tmp_loc] == 1

				B[tmp_loc] = 0;
				B_POS.erase(get_index(tmp_loc));
				COMMON_POS.erase(get_index(tmp_loc));

			}
			update(get_index(tmp_loc));

			break;
		case 'Q':

			B_head_loc = *B_POS.rbegin();

			if(B_head_loc < 0){

				printf("%d\n",getSum(get_index(len_max)));

			}else{

				tmp = calc(B_head_loc+1,get_index(len_max))+B_head_loc-1;

				if(A[B_head_loc-1] == 1){

					printf("%d\n",tmp+1);

				}else{

					if(!COMMON_POS.empty()){

						COMMON_head_loc = *COMMON_POS.rbegin();

						if(is_all_1(COMMON_head_loc+1,B_head_loc,0,0,N-1)){

							printf("%d\n",tmp+1);

						}else{

							printf("%d\n",tmp);
						}

					}else{
						printf("%d\n",tmp);
					}
				}
			}

			break;
		}
	}

	return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 18608
final_rank: 2