题目链接 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;
}