Code: Select all
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <cstdio>
#include <string>
#include <cstring>
#include <set>
#include <algorithm>
#include <ctype.h>
#include <map>
#include <vector>
#include <stack>
#include <climits>
#include <functional>
#include <sstream>
#include <math.h>
using namespace std;
#define lli long long int
#define llu long long unsigned
#define ii pair<int, int>
#define vii vector<ii>
#define vi vector<int>
#define log2(n) log10(n) / log10(2)
#define getMid(a, b) floor(a + b) /2;
#define mii map<int,int>
class SegmentTree{
public:
int tree_len, *tree; int *source; char *stat; int size;
int build(int p, int s, int e){
stat[p] = 'S';
if (s == e)
return tree[p] = (source[s]);
int mid = getMid(s, e);
return tree[p] = build((p<<1), s, mid) + build((p<<1) + 1, mid + 1, e);
}
SegmentTree(int *ex , int n){
size = n;
int h = ceil(log2(size));
source = new int [n]; stat = new char [n];
for (int i = 0; i < n; i++)
source[i] = ex[i];
tree_len = 2 * pow(2, h);
tree = new int[tree_len+1];
build(1, 0, size-1);
}
void rUpdate(int p, int s, int e, int qs, int qe, char com){
if (s > qe || e < qs)
return;
if (s == e){
if (com == 'I') tree[p] =(tree[p] == 1? 0 : 1);
else if (com == 'F') tree[p] = 1;
else source[s] = tree[p] = 0;
stat[p] = 'S';
}
else{
int mid = getMid(s, e);
if (e <= qe && s >= qs){
stat[p] = com; int range = e -s + 1;
if (stat[p] == 'F') tree[p] = range;
else if (stat[p] == 'E') tree[p] = 0;
else if (stat[p] == 'I') tree[p] = range - tree[p];
stat[p<<1] = stat[(p<<1) + 1] = stat[p];
return;
}
rUpdate ((p<<1), s, mid, qs, qe, com);
rUpdate ((p<<1)+ 1, mid+1, e, qs, qe, com);
tree[p] = tree[(p<<1)] + tree[(p<<1)+1];
}
}
int getSum(int p, int s, int e, int i, int j){
if (s > j || e < i)
return 0;
if (s == e)
return tree[p];
if ( s >= i && e <= j)
{
if (stat[p] == 'S')
return tree[p];
int range = e - s + 1;
if (stat[p] == 'F') tree[p] = range;
else if (stat[p] == 'E') tree[p] = 0;
else if (stat[p] == 'I') tree[p] = range - tree[p];
stat[(p<<1)+1] = stat[p<<1] = stat[p];
stat[p] = 'S';
return tree[p];
}
int mid = getMid(s, e);
return getSum((p<<1), s, mid, i, j) + getSum((p<<1)+1, mid + 1, e, i, j);
}
};
int main(){
int *source = new int[1024001];
int T; cin >> T;
for (int tc = 1; tc <= T; tc++){
int m; cin >> m;
int size = 0;
for (int i = 0; i < m; i++)
{
int time; cin >> time;
string orig; cin >> orig;
for (int j = 0; j < time; j++)
for (int k = 0; k < orig.size(); k++)
source[size++] = orig[k] - '0';
}
SegmentTree st(source, size);
cout << "Case " << tc << ":\n";
int q; cin >> q; int god = 0;
for (int i = 0; i < q; i++){
int s, e; char a;
cin >> a >> s >> e;
if (a != 'S') st.rUpdate(1, 0, st.size -1, s, e, a);
else cout << "Q"<<++god << ": " <<st.getSum(1, 0, st.size -1, s, e) << "\n";
}
}
delete [] source;
}