Uva 11402 Ahoy, Pirates! 线段树成段更新



#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 1024005;
const int Mod = 1000000007;
int n,op,x,y;
char str[maxn];
int p[maxn],temp[maxn];
struct node
{
	int c,sum;
}tree[maxn*4];
void PushUp( int rt )
{
	tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum;
}
void PushDown( int rt,int ld,int rd )
{
	if( tree[rt].c != -1 )
	{
		int mid = (ld+rd)>>1;
		tree[rt<<1].c = tree[rt<<1|1].c = tree[rt].c;
		tree[rt<<1].sum = (mid - ld + 1)*tree[rt].c;
		tree[rt<<1|1].sum = (rd - mid)*tree[rt].c;
		tree[rt].c = -1;
	}
}
void BuildTree( int rt,int ld,int rd )
{
	if( ld == rd )
	{
		tree[rt].c = tree[rt].sum = p[ld];
		return;
	}
	int mid = (ld+rd)>>1;
	BuildTree( rt<<1,ld,mid );
	BuildTree( rt<<1|1,mid+1,rd );
	PushUp( rt );	
	if( tree[rt<<1].sum + tree[rt<<1|1].sum == rd - ld +1 )
		tree[rt].c = 1;
	else if( tree[rt<<1].sum + tree[rt<<1|1].sum == 0 )
		tree[rt].c = 0;
	else
		tree[rt].c = -1;
}
void updata( int rt,int ld,int rd,int op )
{
	if( x <= ld && rd <= y &&  !( op == -1 && tree[rt].c == -1 ) )
	{
		if( op == -1 )
		{
			tree[rt].c = 1 - tree[rt].c;
			tree[rt].sum = ( rd - ld + 1)*tree[rt].c;
		}
		else
		{
			tree[rt].c = op;
			tree[rt].sum = ( rd - ld + 1)*tree[rt].c;
		}
		return;
	}
	PushDown( rt,ld,rd );
	int mid = (ld+rd)>>1;
	if( x <= mid )
		updata( rt<<1,ld,mid,op );
	if( y > mid )
		updata( rt<<1|1,mid+1,rd,op );
	PushUp( rt );
}
int query( int rt,int ld,int rd )
{
	if( x <= ld && rd <= y )
	{
		return tree[rt].sum;
	}
	else if( rd < x || y < ld  )
		return 0;
	PushDown( rt,ld,rd );
	int mid = (ld+rd)>>1;
	return  query( rt<<1,ld,mid ) + query( rt<<1|1,mid+1,rd );	
}
int main()
{
#ifndef ONLINE_JUDGE   
	freopen("data.txt","r",stdin);   
#endif
	char ch[4];
	int cas,tmp,cnt,len,q,c = 1;
	scanf("%d",&cas);
	while( cas -- )
	{
		n = 0;
		scanf("%d",&tmp);
		for( int i = 0; i < tmp; i ++ )
		{
			scanf("%d",&cnt);
			scanf("%s",str);
			len = strlen( str );
			for( int j = 0; j < len; j ++ )
			{
				temp[j] = str[j] - '0';
			}
			for( int j = 0; j < cnt; j ++ )
			{
				for( int k = 0; k < len; k ++ )
					p[n++] = temp[k];
			}
		}
		BuildTree( 1,0,n-1 );
		int Q = 1;
		printf("Case %d:\n",c++);
		scanf("%d",&q);
		for( int i = 0; i < q; i ++ )
		{
			scanf("%s%d%d",ch,&x,&y);
			if( ch[0] == 'F' )
			{
				updata( 1,0,n-1,1 );
			}
			else if( ch[0] == 'E' )
			{
				updata( 1,0,n-1,0 );
			}
			else if( ch[0] == 'I' )
			{
				updata( 1,0,n-1,-1 );
			}
			else if( ch[0] == 'S' )
			{
				printf("Q%d: %d\n",Q++,query( 1,0,n-1 ));
			}
		}
	}
	return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值