Can you answer these queries? HDU - 4027 线段树

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=4027


思路:区间查询套用模板,关键是区间更新的时候,区间更新的时候要对每一个点取平方根的操作,要注意的是每一个点最多取7次根号就可以到1,所以当区间的和等于区间长度,就不需要再进行更新。 每一个down的操作就等于单点更新+区间判断.

坑点就是,给的x,y  并不一定满足x<y , 需要进行判断!!


#include <iostream> 
#include <cstdio>
#include <math.h>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5+10; 
long long value[N*4]; 
int n;
void down( int root , int l, int r )  {
	if ( r-l+1==value[root] ) return ;
	if ( l==r ) {
		value[root] = sqrt( value[root] ) ; 
		return ;  
	}
	int mid = ( l+r )/2 ; 
	down( root*2  , l , mid ) ; 
	down( root*2+1,mid+1 ,r ) ;  
	value[root] = value[root*2]+value[root*2+1]; 
	return ; 
}
void build( int root,int l,int r ) {
	if( l==r ) {
		scanf("%lld",&value[root]);  
		return ; 
	}
	int mid = ( l+r )/2 ; 
	build( root*2,l,mid);
	build( root*2+1,mid+1,r); 
	value[root] = value[root*2] + value[root*2+1]; 
}

void update(int root,int l,int r,int x,int y ) {
	if ( y<l || x>r ) return ; 
	if ( x<=l && y>=r ) {
		down( root,l,r ); 
		return ;
	}
	int mid = ( l+r )/2 ; 
	update( root*2,l,mid,x,y ) ; 
	update( root*2+1,mid+1,r,x,y ); 
	value[root] = value[root*2] + value[root*2+1]; 
	return ; 
}

long long query( int root,int l,int r,int x,int y ) {
	if ( y<l || x>r ) return 0 ;
	if ( x<=l && y>=r ) return value[root] ; 	
	int mid = ( l+r )/2 ; 
	return query( root*2,l,mid,x,y)+query( root*2+1,mid+1,r,x,y); 
}
int main()
{
	int cases =0 ;
	int m; 
	int choice; 
	int x,y;  
	while ( scanf("%d",&n)!=EOF ) {
		build( 1,1,n ); 
		++cases;
		printf("Case #%d:\n",cases);	
		cin>>m; 
		while( m-- ) { 	
			scanf("%d%d%d",&choice,&x,&y);
			if ( x>y ) swap(x,y); 
			if ( choice ) cout<<query(1,1,n,x,y)<<endl; 	
			else update( 1,1,n,x,y); 
		}
		cout<<endl; 
	}
	return 0; 
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值