给定一个序列,有两种操作:对一个区间内的数字开方和求区间内所有数字的和。注意到一个即使很大的数经过没几次开方操作以后就会变成1,而1开方还是1。所以可以用线段树来维护,对于那些全部都是1的区间(即区间和等于区间长度)我们不用更新,剩下的就是区间求和了。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cmath> 5 using namespace std; 6 7 typedef long long ll; 8 const int N = 100001; 9 ll a[N]; 10 int n, m; 11 12 struct Node 13 { 14 int l, r; 15 ll sum; 16 } node[N << 2]; 17 18 void pushup( int i ) 19 { 20 node[i].sum = node[i << 1].sum + node[i << 1 | 1].sum; 21 } 22 23 void build( int i, int l, int r ) 24 { 25 node[i].l = l, node[i].r = r; 26 if ( l == r ) 27 { 28 node[i].sum = a[l]; 29 return ; 30 } 31 int mid = ( l + r ) >> 1; 32 build( i << 1, l, mid ); 33 build( i << 1 | 1, mid + 1, r ); 34 pushup(i); 35 } 36 37 void update( int i, int l, int r ) 38 { 39 int len = node[i].r - node[i].l + 1; 40 if ( node[i].sum == len ) return ; 41 int mid = ( node[i].l + node[i].r ) >> 1; 42 if ( node[i].l == l && node[i].r == r ) 43 { 44 if ( len == 1 ) 45 { 46 node[i].sum = sqrt( node[i].sum * 1.0 ); 47 } 48 else 49 { 50 update( i << 1, l, mid ); 51 update( i << 1 | 1, mid + 1, r ); 52 pushup(i); 53 } 54 return ; 55 } 56 if ( r <= mid ) 57 { 58 update( i << 1, l, r ); 59 } 60 else if ( l > mid ) 61 { 62 update( i << 1 | 1, l, r ); 63 } 64 else 65 { 66 update( i << 1, l, mid ); 67 update( i << 1 | 1, mid + 1, r ); 68 } 69 pushup(i); 70 } 71 72 ll query( int i, int l, int r ) 73 { 74 if ( node[i].l == l && node[i].r == r ) 75 { 76 return node[i].sum; 77 } 78 int mid = ( node[i].l + node[i].r ) >> 1; 79 if ( r <= mid ) 80 { 81 return query( i << 1, l, r ); 82 } 83 else if ( l > mid ) 84 { 85 return query( i << 1 | 1, l, r ); 86 } 87 else 88 { 89 return query( i << 1, l, mid ) + query( i << 1 | 1, mid + 1, r ); 90 } 91 } 92 93 int main () 94 { 95 int _case = 1; 96 while ( scanf("%d", &n) != EOF ) 97 { 98 printf("Case #%d:\n", _case++); 99 for ( int i = 1; i <= n; i++ ) 100 { 101 scanf("%lld", &a[i]); 102 } 103 build( 1, 1, n ); 104 scanf("%d", &m); 105 while ( m-- ) 106 { 107 int op, x, y; 108 scanf("%d%d%d", &op, &x, &y); 109 if ( x > y ) swap( x, y ); 110 if ( op == 0 ) 111 { 112 update( 1, x, y ); 113 } 114 else 115 { 116 ll ans = query( 1, x, y ); 117 printf("%lld\n", ans); 118 } 119 } 120 putchar(‘\n‘); 121 } 122 return 0; 123 }
时间: 2024-10-22 20:27:59