11402

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>

#define sz 1024001
#define INV 1
#define SET 2
#define RESET 3

using namespace std;

struct segment{
	int pending_op_typ;
	int sum;

	int left,right;
	int len;
};
segment tree[sz*4];
string ss;

void init(int node,int b,int e)
{
	tree[node].len = e-b+1;
	tree[node].left=b;
	tree[node].right=e;
	tree[node].pending_op_typ=0;
	if(b==e)
	{

		if(ss[b]=='1')
		tree[node].sum=1;
		else
		tree[node].sum=0;
		return;
	}
	int Left = node*2;
	int Right = (node<<1)|1;
	int mid = (b+e)>>1;
	init(Left,b,mid);
	init(Right,mid+1,e);
	tree[node].sum=tree[Left].sum+tree[Right].sum;
}

void change(int node,int opr)
{
	if(opr==SET)
	{
		tree[node].sum=tree[node].len;
		tree[node].pending_op_typ=opr;
	}
	else if(opr==RESET)
	{
		tree[node].sum=0;
		tree[node].pending_op_typ=opr;
	}
	else if(opr==INV)
	{
		tree[node].sum=tree[node].len-tree[node].sum;
		if(tree[node].pending_op_typ==SET)//inverse the operation and apply
		{
			tree[node].pending_op_typ=RESET;
		}
		else if(tree[node].pending_op_typ==RESET)//inverse the operation and apply
		{
			tree[node].pending_op_typ=SET;
		}
		else if(tree[node].pending_op_typ==INV)//inverse the operation and apply
		{
			tree[node].pending_op_typ=0;
		}
		else if(tree[node].pending_op_typ==0)//inverse the operation and apply
		{
			tree[node].pending_op_typ=INV;
		}
	}

}

void propagate(int node)
{
	if(tree[node].pending_op_typ==0)
	return;
	int Left=2*node;
	int Right=2*node+1;
	change(Left,tree[node].pending_op_typ);
	change(Right,tree[node].pending_op_typ);
	tree[node].pending_op_typ=0;
}

int query(int node,int i,int j)
{
	int b=tree[node].left;
	int e=tree[node].right;
	if(i>e || j<b)
	return 0;
	propagate(node);
	if(i<=b && j>=e)
	{
		return tree[node].sum;
	}
	else
	{
		int Left = node<<1;
		int Right = (node<<1)|1;
		int p1 = query(Left,i,j);
		int p2 = query(Right,i,j);
		return p1+p2;
	}
}


void update(int node,int i,int j,int opr)
{
	int left = tree[node].left,right=tree[node].right;
	propagate(node);
	if(i>right || j<left)
	return;
	if(left>=i && right<=j)
	{
		change(node,opr);
		return;
	}
	else
	{
		int Left = node*2;
		int Right = node*2+1;
		update(Left,i,j,opr);
		update(Right,i,j,opr);
		tree[node].sum=tree[Left].sum+tree[Right].sum;
	}
}
// 0 for Barbary, 1 for Buccaneer
int main()
{
	int t,tym,M,qry;
	int a,b;
	int kase=1,cnt;
	bool flag;
	string s,str;
	scanf("%d",&t);

	while(t--)
	{
		flag=0;
		cnt=1;
		scanf("%d",&tym);
		s="";
		while(tym--)
		{
			scanf("%d",&M);
			cin>>str;
			while(M--)
				s.append(str);
		}
		ss = "2";
		ss.append(s);
		init(1,1,ss.size()-1);//init(1,1,ss.size()-1);
		scanf("%d",&qry);
		while(qry--)
		{
			cin>>str;
			scanf("%d%d",&a,&b);
			if(str=="F")
			{
				update(1,a+1,b+1,SET);//convert to buccaneer
			}
			else if(str=="E")
			{
				update(1,a+1,b+1,RESET);//convert to barbary =0
			}
			else if(str=="I")
			{
				update(1,a+1,b+1,INV);//inverse the pirates
			}
			else if(str=="S")
			{
				if(flag==0)
				{
					cout<<"Case "<<kase++<<":\n";
				}
				flag=1;
				cout<<"Q"<<cnt++<<": ";
				cout<<query(1,a+1,b+1)<<"\n";
			}
		}
	}
	return 0;
}

 

Leave a Reply

Your email address will not be published. Required fields are marked *