hdu4605 Magic Ball Game

本文介绍了一种使用树状数组和自定义数据结构解决特定问题的算法实现方案,涉及节点更新、区间查询等操作,并通过示例展示了如何在具体场景中应用这些技术。
#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
using namespace std ;

const int maxn = 111111 * 2 ;

struct Ans
{
	int x , y ;
} ans[maxn] ;

struct Point
{
	int x , v ;
} p[maxn] ;

struct Node
{
	int id , x ;
} ;

vector<Node> vec[maxn] ;

int c1[maxn] , c2[maxn] , lson[maxn] , rson[maxn] , w[maxn] , f[maxn] , tot ;

int lowbit ( int x ) { return x & (-x) ; }

void update ( int pos , int v , int flag )
{
	while ( pos <= maxn - 10 )
	{
		if ( flag ) c1[pos] += v ;
		else c2[pos] += v ;
		pos += lowbit ( pos ) ;
	}
}

int sum ( int pos , int flag )
{
	int ret = 0 ;
	while ( pos > 0 )
	{
		if ( flag ) ret += c1[pos] ;
		else ret += c2[pos] ;
		pos -= lowbit ( pos ) ;
	}
	return ret ;
}

void init ( int n )
{
	int i ;
	memset ( c1 , 0 , sizeof ( c1 ) ) ;
	memset ( c2 , 0 , sizeof ( c2 ) ) ;
	for ( i = 0 ; i <= n ; i ++ )
	{
		lson[i] = rson[i] = 0 ;
		vec[i].clear () ;
	}
}

void dfs ( int u )
{
	int i , j , a1 , a2 , b1 , b2 , k ;
	Node e ;
	for ( i = 0 ; i < vec[u].size () ; i ++ )
	{
		e = vec[u][i] ;
		int x = e.x , id = e.id ;
		if ( u == 1 ) ans[id].x = ans[id].y = 0 ;
		else if ( sum ( x , 1 ) != sum ( x - 1 , 1 ) || sum ( x , 0 ) != sum ( x - 1 , 0 ) )
			ans[id].x = -1 ;
		else
		{
			a1 = sum ( maxn - 10 , 1 ) - sum ( x , 1 ) ;
			b1 = sum ( x - 1 , 1 ) ;
			a2 = sum ( maxn - 10 , 0 ) - sum ( x , 0 ) ;
			b2 = sum ( x - 1 , 0 ) ;
			ans[id].x = b2 ;
			ans[id].y = a1 + b1 * 3 + a2 + 3 * b2 ;
		}
	}
	if ( lson[u] )
	{
		update ( w[u] , 1 , 1 ) ;
		dfs ( lson[u] ) ;
		update ( w[u] , -1 , 1 ) ;
	}
	if ( rson[u] )
	{
		update ( w[u] , 1 , 0 ) ;
		dfs ( rson[u] ) ;
		update ( w[u] , -1 , 0 ) ;
	}
}

int main ()
{
	int cas , n , m , q , i , j , k ;
	scanf ( "%d" , &cas ) ;
	Node u ;
	while ( cas -- )
	{
		scanf ( "%d" , &n ) ;
		init ( n ) ;
		tot = 0 ;
		for ( i = 1 ; i <= n ; i ++ ) scanf ( "%d" , &w[i] ) , f[++tot] = w[i] ;
		scanf ( "%d" , &m ) ;
		while ( m -- )
		{
			int a , b , c ;
			scanf ( "%d%d%d" , &a , &b , &c ) ;
			lson[a] = b , rson[a] = c ;
		}
		scanf ( "%d" , &q ) ;
		for ( i = 1 ; i <= q ; i ++ )
		{
			scanf ( "%d%d" , &p[i].v , &p[i].x ) ;
			f[++tot] = p[i].x ;
		}
		sort ( f + 1 , f + tot + 1 ) ;
		tot = unique ( f + 1 , f + tot + 1 ) - f - 1 ;
		for ( i = 1 ; i <= n ; i ++ ) w[i] = lower_bound ( f + 1 , f + tot + 1 , w[i] ) - f ;
		for ( i = 1 ; i <= q ; i ++ )
		{
			u.id = i ;
			u.x = lower_bound ( f + 1 ,  f + tot + 1 , p[i].x ) - f ;
			vec[p[i].v].push_back ( u ) ;
		}
		dfs ( 1 ) ;
		for ( i = 1 ; i <= q ; i ++ )
		{
			if ( ans[i].x == -1 ) puts ( "0" ) ;
			else printf ( "%d %d\n" , ans[i].x , ans[i].y ) ;
		}
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值