# bzoj 3211 线段树

 1 /**************************************************************
2     Problem: 3211
3     User: idy002
4     Language: C++
5     Result: Accepted
6     Time:1976 ms
7     Memory:7068 kb
8 ****************************************************************/
9
10 #include <cstdio>
11 #include <cmath>
12 #define N 100010
13
14 typedef long long dnt;
15 struct Node {
16     dnt s;
17     bool t;
18     Node *ls, *rs;
19 }pool[N*3], *tail=pool, *root;
20
21 int n, m;
22 int aa[N];
23
24 Node *build( int lf, int rg ) {
25     Node *nd = ++tail;
26     if( lf==rg ) {
27         nd->s = aa[lf];
28         nd->t = aa[lf]<=1;
29         return nd;
30     }
31     int mid=(lf+rg)>>1;
32     nd->ls = build( lf, mid );
33     nd->rs = build( mid+1, rg );
34     nd->s = nd->ls->s + nd->rs->s;
35     nd->t = nd->ls->t && nd->rs->t;
36     return nd;
37 }
38 void modify( Node *nd, int lf, int rg, int L, int R ) {
39     if( lf==rg ) {
40         nd->s = (dnt)sqrt(nd->s);
41         nd->t = nd->s<=1;
42         return;
43     }
44     if( nd->t ) return;
45     int mid=(lf+rg)>>1;
46     if( L<=mid ) modify( nd->ls, lf, mid, L, R );
47     if( R>mid ) modify( nd->rs, mid+1, rg, L, R );
48     nd->s = nd->ls->s + nd->rs->s;
49     nd->t = nd->ls->t && nd->rs->t;
50 }
51 dnt query( Node *nd, int lf, int rg, int L, int R ) {
52     if( L<=lf && rg<=R ) return nd->s;
53     int mid=(lf+rg)>>1;
54     dnt rt = 0;
55     if( L<=mid ) rt+=query( nd->ls, lf, mid, L, R );
56     if( R>mid ) rt+=query( nd->rs, mid+1, rg, L, R );
57     return rt;
58 }
59
60 int main() {
61     scanf( "%d", &n );
62     for( int i=1; i<=n; i++ )
63         scanf( "%d", aa+i );
64     root = build( 1, n );
65     scanf( "%d", &m );
66     for( int i=1,opt,l,r; i<=m; i++ ) {
67         scanf( "%d%d%d", &opt, &l, &r );
68         if( opt==1 )
69             printf( "%lld\n", query(root,1,n,l,r) );
70         else
71             modify(root,1,n,l,r);
72     }
73 }
View Code

posted @ 2015-06-06 19:02  idy002  阅读(110)  评论(0编辑  收藏  举报