HDU4027 (线段树/修改区间,询问区间和)
lazy思想
当一个数开了6到7次根号时,就变成1了。
View Code
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 #include<algorithm> 5 #include<math.h> 6 using namespace std; 7 typedef __int64 int64; 8 #define L( x ) (x<<1) 9 #define R( x ) ((x<<1)+1) 10 const int64 maxn = 100005; 11 struct node{ 12 int64 l,r,num; 13 }anode[ maxn*4 ]; 14 int64 data[ maxn ]; 15 16 void build( int64 l,int64 r,int64 n ){ 17 if( l==r ){ 18 anode[ n ].l=l,anode[ n ].r=r,anode[ n ].num=data[ l ]; 19 return ; 20 } 21 int64 mid; 22 mid=( l+r )/2; 23 anode[ n ].l=l,anode[ n ].r=r; 24 build( l,mid,L( n ) ); 25 build( mid+1,r,R( n )); 26 anode[ n ].num=anode[ L( n ) ].num+anode[ R( n ) ].num; 27 return ; 28 }//build the tree 29 30 void update( int64 l,int64 r,int64 n ){ 31 if( anode[ n ].num==( anode[ n ].r-anode[ n ].l+1 ) ) return ;//一个数经过6,7次开根号就能变成1 32 if( anode[ n ].l==anode[ n ].r ) { 33 anode[ n ].num=sqrt( 1.0*anode[ n ].num ); 34 return ; 35 } 36 int64 mid; 37 mid=( anode[ n ].l+anode[ n ].r )/2; 38 if( mid>=r ) update( l,r,L( n ) ); 39 else if( mid<l ) update( l,r,R( n ) ); 40 else {update( l,mid,L( n ) );update( mid+1,r,R( n ) );} 41 anode[ n ].num=anode[ L( n ) ].num+anode[ R( n ) ].num; 42 return ; 43 } 44 45 int64 query( int64 l,int64 r,int64 n ){ 46 if( anode[ n ].l==l && anode[ n ].r==r ) return anode[ n ].num; 47 int64 mid; 48 mid=( anode[ n ].l+anode[ n ].r )/2; 49 if( mid>=r ) return query( l,r,L( n ) ); 50 else if( mid<l ) return query( l,r,R( n ) ); 51 else return( query( l,mid,L( n ) )+query( mid+1,r,R( n ) ) ); 52 } 53 54 int main(){ 55 int64 n; 56 int64 ca=1; 57 while( scanf("%I64d",&n)!=EOF ){ 58 printf("Case #%I64d:\n",ca++); 59 for( int64 i=1;i<=n;i++ ){ 60 scanf("%I64d",&data[ i ]); 61 } 62 build( 1,n,1 ); 63 int64 tmp; 64 scanf("%I64d",&tmp); 65 while( tmp-- ){ 66 int64 temp,a,b; 67 scanf("%I64d%I64d%I64d",&temp,&a,&b); 68 int64 j; 69 if(a>b){j=a;a=b;b=j;} 70 if(temp==0) 71 update( a,b,1 ); 72 else 73 printf("%I64d\n",query( a,b,1 )); 74 } 75 printf("\n"); 76 } 77 return 0; 78 }
keep moving...