zoukankan      html  css  js  c++  java
  • 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     else
    121     {
    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             else
    145             {
    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             else
    135             {
    136                 cout << query( 1 , x , y ) << endl;
    137             }
    138         }
    139     }
    140     return 0;
    141 }
    View Code

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

    today:

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

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

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

    just follow your heart
  • 相关阅读:
    IOS Charles(代理服务器软件,可以用来拦截网络请求)
    Javascript中addEventListener和attachEvent的区别
    MVC中实现Area几种方法
    Entity Framework Code First 中使用 Fluent API 笔记。
    自定义JsonResult解决 序列化类型 System.Data.Entity.DynamicProxies 的对象时检测到循环引用
    序列化类型 System.Data.Entity.DynamicProxies 的对象时检测到循环引用
    An entity object cannot be referenced by multiple instances of IEntityChangeTracker 的解决方案
    Code First :使用Entity. Framework编程(8) ----转发 收藏
    Code First :使用Entity. Framework编程(6) ----转发 收藏
    Code First :使用Entity. Framework编程(5) ----转发 收藏
  • 原文地址:https://www.cnblogs.com/radical/p/4063758.html
Copyright © 2011-2022 走看看