首页 > 代码库 > hdu--3911--线段树<我最近爱上她了>

hdu--3911--线段树<我最近爱上她了>

突然间 觉得 线段树是个很优美的数据结构~~ 太灵活了 通过几个var 可以完成太多功能

这题其实我也想说 好累啊 写的...但似乎 因为它是线段树的缘故就显得很平常了...

这里主要考察了lazy标记---延迟父节点对子节点的更新

这边还算简单的 只需要1个Lazy标记 麻烦的是需要2个 甚至3个的...

这边至于 黑白关系 就是一个 异或运算 可以搞定

要注意下 询问一段区间内 最长的连续的1的个数 必须分成3段来考虑  通过是否包含中点 来划分 左 右 中

虽然 这边是问最长的连续的1的个数 但我有必要记录下最长的连续0的个数 因为这样进行一个Update后 答案就是变成了刚才的最长的连续0的个数

这边我们分别需要考虑一个区间从左边与右边分别来看的 含连续0或1的最长区间 再统一考虑得出一个区间内最长连续0或1的长度

真的  线段树 需要思考的范围很多

这边的话 我分别试了下 2种不同的对于区间进行操作的方式 发现时间上第一种 更加快点

  1 /*  2 线段树所有节点理论空间值是2n-1,但是实际上所占空间会超过这个数。因为一颗线段树的高度是log(n - 1) + 1,  3 而线段树是完全二叉树,所以要开够最后一层,所以总的空间就是1+2^1 + ... + 2^(log(n - 1) + 1) = 4(n - 1) - 1。  4 所以保守要开4倍空间,但是大多数情况下3倍空间也是能过的。  5 */  6 #include <iostream>  7 #include <algorithm>  8 using namespace std;  9  10 const int size = 100010; 11 struct data  // 1是黑色  0是白色 12 { 13     int L; 14     int R; 15     int len; 16     int Lone , Rone , Lzero , Rzero , maxOne  , maxZero; 17     int color; 18 }tree[size*4]; 19  20 void solve( int root ) 21 { 22     swap( tree[root].Lone , tree[root].Lzero ); 23     swap( tree[root].Rone , tree[root].Rzero ); 24     swap( tree[root].maxOne , tree[root].maxZero ); 25     tree[root].color ^= 1; 26 } 27  28 void pushUp( int root ) 29 { 30     tree[root].Lone = tree[root<<1].Lone; 31     if( tree[root<<1].Lone == tree[root<<1].len ) 32         tree[root].Lone += tree[root<<1|1].Lone; 33  34     tree[root].Lzero = tree[root<<1].Lzero; 35     if( tree[root<<1].Lzero == tree[root<<1].len ) 36         tree[root].Lzero += tree[root<<1|1].Lzero; 37  38     tree[root].Rone = tree[root<<1|1].Rone; 39     if( tree[root<<1|1].Rone == tree[root<<1|1].len ) 40         tree[root].Rone += tree[root<<1].Rone; 41  42     tree[root].Rzero = tree[root<<1|1].Rzero; 43     if( tree[root<<1|1].Rzero == tree[root<<1|1].len ) 44         tree[root].Rzero += tree[root<<1].Rzero; 45  46     tree[root].maxOne = max( max( tree[root<<1].maxOne , tree[root<<1|1].maxOne ) , tree[root<<1].Rone + tree[root<<1|1].Lone ); 47     tree[root].maxZero = max( max( tree[root<<1].maxZero , tree[root<<1|1].maxZero) , tree[root<<1].Rzero + tree[root<<1|1].Lzero ); 48 } 49  50 void pushDown( int root ) 51 { 52     solve( root<<1 ); 53     solve( root<<1|1 ); 54     tree[root].color = 0; 55 } 56  57 void build( int root , int L , int R ) 58 { 59     int Mid = ( L + R ) >> 1 , num; 60     tree[root].L = L; 61     tree[root].R = R; 62     tree[root].len = R - L + 1; 63     tree[root].color = 0; 64     if( L==R ) 65     { 66         cin >> num; 67         if( num == 1 ) 68         { 69             tree[root].Lone =  tree[root].Rone = tree[root].maxOne = 1; 70             tree[root].Lzero = tree[root].Rzero = tree[root].maxZero = 0; 71         } 72         else 73         { 74             tree[root].Lone = tree[root].Rone = tree[root].maxOne = 0; 75             tree[root].Lzero = tree[root].Rzero = tree[root].maxZero = 1; 76         } 77         return; 78     } 79     build( root<<1 , L , Mid ); 80     build( root<<1|1 , Mid+1 , R ); 81     pushUp( root ); 82 } 83  84 void update( int root , int L , int R ) 85 { 86     int Mid = ( tree[root].L + tree[root].R ) >> 1; 87     if( tree[root].L == L && tree[root].R == R ) 88     { 89         solve( root ); 90         return; 91     } 92     if( tree[root].color ) 93         pushDown( root ); 94     if( R <= Mid ) 95         update( root<<1 , L , R ); 96     else if( L >= Mid+1 ) 97         update( root<<1|1 , L , R ); 98     else 99     {100         update( root<<1 , L , Mid );101         update( root<<1|1 , Mid+1 , R );102     }103     pushUp( root );104 }105 106 int query( int root , int L , int R )107 {108     int a = 0 , b = 0 , var = 0;109     int Mid = ( tree[root].L + tree[root].R ) >> 1;110     if( tree[root].L == L && tree[root].R == R )111     {112         return tree[root].maxOne;113     }114     if( tree[root].color )115         pushDown( root );116     if( R <= Mid )117         return query( root<<1 , L , R );118     else if( L >= Mid+1 )119         return query( root<<1|1 , L , R );120     else121     {122         a = query( root<<1 , L , Mid );123         b = query( root<<1|1 , Mid+1 , R );124         var = min( Mid - L + 1 , tree[root<<1].Rone ) + min( R - Mid , tree[root<<1|1].Lone );125         return max( max(a,b) , var );126     }127 }128 129 int main()130 {131     cin.sync_with_stdio(false);132     int n , m , x , y , op;133     while( cin >> n )134     {135         build( 1 , 1 , n );136         cin >> m;137         while( m-- )138         {139             cin >> op >> x >> y;140             if( op == 1 )141             {142                 update( 1 , x , y );143             }144             else145             {146                 cout << query( 1 , x , y ) << endl;147             }148         }149     }150     return 0;151 }
View Code

 

  1 /*  2 线段树所有节点理论空间值是2n-1,但是实际上所占空间会超过这个数。因为一颗线段树的高度是log(n - 1) + 1,  3 而线段树是完全二叉树,所以要开够最后一层,所以总的空间就是1+2^1 + ... + 2^(log(n - 1) + 1) = 4(n - 1) - 1。  4 所以保守要开4倍空间,但是大多数情况下3倍空间也是能过的。  5 */  6 #include <iostream>  7 #include <algorithm>  8 using namespace std;  9  10 const int size = 100010; 11 struct data  // 1是黑色  0是白色 12 { 13     int L; 14     int R; 15     int len; 16     int Lone , Rone , Lzero , Rzero , maxOne  , maxZero; 17     int color; 18 }tree[size*4]; 19  20 void solve( int root ) 21 { 22     swap( tree[root].Lone , tree[root].Lzero ); 23     swap( tree[root].Rone , tree[root].Rzero ); 24     swap( tree[root].maxOne , tree[root].maxZero ); 25     tree[root].color ^= 1; 26 } 27  28 void pushUp( int root ) 29 { 30     tree[root].Lone = tree[root<<1].Lone; 31     if( tree[root<<1].Lone == tree[root<<1].len ) 32         tree[root].Lone += tree[root<<1|1].Lone; 33  34     tree[root].Lzero = tree[root<<1].Lzero; 35     if( tree[root<<1].Lzero == tree[root<<1].len ) 36         tree[root].Lzero += tree[root<<1|1].Lzero; 37  38     tree[root].Rone = tree[root<<1|1].Rone; 39     if( tree[root<<1|1].Rone == tree[root<<1|1].len ) 40         tree[root].Rone += tree[root<<1].Rone; 41  42     tree[root].Rzero = tree[root<<1|1].Rzero; 43     if( tree[root<<1|1].Rzero == tree[root<<1|1].len ) 44         tree[root].Rzero += tree[root<<1].Rzero; 45  46     tree[root].maxOne = max( max( tree[root<<1].maxOne , tree[root<<1|1].maxOne ) , tree[root<<1].Rone + tree[root<<1|1].Lone ); 47     tree[root].maxZero = max( max( tree[root<<1].maxZero , tree[root<<1|1].maxZero) , tree[root<<1].Rzero + tree[root<<1|1].Lzero ); 48 } 49  50 void pushDown( int root ) 51 { 52     solve( root<<1 ); 53     solve( root<<1|1 ); 54     tree[root].color = 0; 55 } 56  57 void build( int root , int L , int R ) 58 { 59     int Mid = ( L + R ) >> 1 , num; 60     tree[root].L = L; 61     tree[root].R = R; 62     tree[root].len = R - L + 1; 63     tree[root].color = 0; 64     if( L==R ) 65     { 66         cin >> num; 67         if( num == 1 ) 68         { 69             tree[root].Lone =  tree[root].Rone = tree[root].maxOne = 1; 70             tree[root].Lzero = tree[root].Rzero = tree[root].maxZero = 0; 71         } 72         else 73         { 74             tree[root].Lone = tree[root].Rone = tree[root].maxOne = 0; 75             tree[root].Lzero = tree[root].Rzero = tree[root].maxZero = 1; 76         } 77         return; 78     } 79     build( root<<1 , L , Mid ); 80     build( root<<1|1 , Mid+1 , R ); 81     pushUp( root ); 82 } 83  84 void update( int root , int L , int R ) 85 { 86     int Mid = ( tree[root].L + tree[root].R ) >> 1; 87     if( tree[root].L >= L && tree[root].R <= R ) 88     { 89         solve( root ); 90         return; 91     } 92     if( tree[root].color ) 93         pushDown( root ); 94     if( L <= Mid ) 95         update( root<<1 , L , R ); 96     if( R >= Mid+1 ) 97         update( root<<1|1 , L , R ); 98     pushUp( root ); 99 }100 101 int query( int root , int L , int R )102 {103     int a = 0 , b = 0 , var = 0;104     int Mid = ( tree[root].L + tree[root].R ) >> 1;105     if( tree[root].L >= L && tree[root].R <= R )106     {107         return tree[root].maxOne;108     }109     if( tree[root].color )110         pushDown( root );111     if( L <= Mid )112         a = query( root<<1 , L , R );113     if( R >= Mid+1 )114         b = query( root<<1|1 , L , R );115     var = min( Mid - L + 1 , tree[root<<1].Rone ) + min( R - Mid , tree[root<<1|1].Lone );116     return max( max(a,b) , var );117 }118 119 int main()120 {121     cin.sync_with_stdio(false);122     int n , m , x , y , op;123     while( cin >> n )124     {125         build( 1 , 1 , n );126         cin >> m;127         while( m-- )128         {129             cin >> op >> x >> y;130             if( op == 1 )131             {132                 update( 1 , x , y );133             }134             else135             {136                 cout << query( 1 , x , y ) << endl;137             }138         }139     }140     return 0;141 }
View Code

 

我应该还会继续做几题 来找感觉 蛮有意思的  =_=

 

today:

  努力想得到什么东西,其实只要沉着镇静、实事求是,就可以轻易地、神不知鬼不觉地达到目的。

      而如果过于使劲,闹得太凶,太幼稚,太没有经验,就哭啊,抓啊,拉啊,像一个小孩扯桌布,

      结果却是一无所获,只不过把桌上的好东西都扯到地上,永远也得不到了。

 

hdu--3911--线段树<我最近爱上她了>