您的位置:首页 > 产品设计 > UI/UE

hdu 4027 Can you answer these queries? 线段树

2015-02-09 16:26 411 查看
就是两种操作:1.将选定区间的每个数变成原来的floor(sqrt(x))2.求选定区间的数的总和

开始还想着是不是能够成段更新,将要开根的区间先存着。想想这么写有点太麻烦了因为最后还是要更新到叶子节点才能算答案的。因此直接改成单点更新就好,但是有个重要的剪枝,就是1 == sqrt(1),即一段连续区间的长度 == 该长度总和,也就是该长度内每个点都是1的时候就没必要继续更新下去了。

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <vector>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
#define pi acos(-1.0)
#define eps 1e-8
typedef long long ll;
const int inf = 0x3f3f3f3f;

const int N = 100010;

struct node{
	int l, r;
	ll x;
}tr[N << 2];

void build( int l, int r, int rt )
{
	tr[rt].l = l;
	tr[rt].r = r;
	if( l == r )
	{
		scanf("%lld", &tr[rt].x );
		return;
	}
	int mid = ( l + r ) >> 1;
	build( lson );
	build( rson );
	tr[rt].x = tr[rt<<1].x + tr[rt<<1|1].x;
}
/*
void down( int rt )
{
	int m = ( tr[rt].r - tr[rt].l + 1 );
	if( tr[rt].add )
	{
		tr[rt<<1].add += tr[rt].add;
		tr[rt<<1|1].add += tr[rt].add;
		tr[rt<<1].x += 1LL * ( m - (m >> 1) ) * tr[rt].add;
		tr[rt<<1|1].x += 1LL * ( m >> 1 ) * tr[rt].add;
		tr[rt].add = 0;
	}
}
*/
void update( int l, int r, int rt )
{
	if( tr[rt].x == tr[rt].r - tr[rt].l + 1 )
		return;
	if( tr[rt].r == tr[rt].l )
	{
		tr[rt].x = sqrt( (double) tr[rt].x );
		return;
	}
	int mid = ( tr[rt].l + tr[rt].r ) >> 1;
	if( r <= mid )
		update( l, r, rt << 1 );
	else if( l > mid )
		update( l, r, rt << 1 | 1 );
	else
	{
		update( lson );
		update( rson );
	}
	tr[rt].x = tr[rt<<1].x + tr[rt<<1|1].x;
}

ll query( int l, int r, int rt )
{
	if( l <= tr[rt].l && tr[rt].r <= r )
		return tr[rt].x;
	int mid = ( tr[rt].l + tr[rt].r ) >> 1;
	if( r <= mid )
		return query( l, r, rt << 1);
	else if( l > mid )
		return query( l, r, rt << 1 | 1 );
	else
		return query( lson ) + query( rson );
}

int main()
{
	int cas = 1;
	int n, m;
	int op, l, r;
	while(~scanf("%d", &n))
	{
		build( 1, n, 1 );
		scanf("%d", &m);
		printf("Case #%d:\n", cas++);
		while( m-- )
		{
			scanf("%d%d%d", &op, &l, &r);
			if( l > r )
				swap( l, r );
			if( op == 0 )
				update( l, r, 1 );
			else
			{
				ll ans = query( l, r, 1 );
				printf("%lld\n", ans);
			}
		}
		puts("");
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: