hdu--5023--线段树

算基础的 线段树的区间更新题吧

题意 也很好理解

只是要注意下 输出颜色的时候 递增顺序来输出

  1 #include <iostream>
  2 using namespace std;
  3 
  4 const int size = 1000010;
  5 int ans;
  6 struct node
  7 {    
  8     int L , R;
  9     int color , flag;
 10 }tree[size*4];
 11 
 12 void build( int root , int L , int R )
 13 {
 14     int M = (L+R) >> 1;
 15     tree[root].L = L;
 16     tree[root].R = R;
 17     tree[root].color = 1<<2;
 18     tree[root].flag = 0;
 19     if( L==R)
 20     {    
 21         return ;
 22     }
 23     build( root<<1 , L , M );
 24     build( root<<1|1 , M+1 , R );
 25 }
 26 
 27 void pushDown( int root )
 28 {
 29     tree[root].flag = 0;
 30     tree[root<<1].flag = tree[root<<1|1].flag = 1;
 31     tree[root<<1].color = tree[root<<1|1].color = tree[root].color;
 32 }
 33 
 34 void pushUp( int root )
 35 {
 36     tree[root].color = tree[root<<1].color | tree[root<<1|1].color;
 37 }
 38 
 39 void update( int root , int L , int R , int var )
 40 {
 41     int M = ( tree[root].L + tree[root].R ) >> 1;
 42     if( tree[root].L == L && tree[root].R == R )
 43     {
 44         tree[root].color = 1<<var;
 45         tree[root].flag = 1;
 46         return ;
 47     }
 48     if( tree[root].flag )
 49     {
 50         pushDown( root );
 51     }
 52     if( R<=M )
 53         update( root<<1 , L , R , var );
 54     else if( L>=M+1 )
 55         update( root<<1|1 , L , R , var );
 56     else
 57     {
 58         update( root<<1 , L , M , var );
 59         update( root<<1|1 , M+1 , R , var );
 60     }
 61     pushUp( root );
 62 }
 63 
 64 void query( int root , int L , int R )
 65 {
 66     int M = ( tree[root].L + tree[root].R ) >> 1;
 67     if( tree[root].L == L && tree[root].R == R )
 68     {
 69         ans |= tree[root].color;
 70         return ;
 71     }
 72     if( tree[root].flag )
 73     {
 74         pushDown( root );
 75     }
 76     if( R<=M )
 77         query( root<<1 , L , R );
 78     else if( L>=M+1 )
 79         query( root<<1|1 , L , R );
 80     else
 81     {
 82         query( root<<1 , L , M );
 83         query( root<<1|1 , M+1 , R );
 84     }
 85     pushUp( root );
 86 }
 87 
 88 void solve( )
 89 {
 90     bool flag = true;
 91     for( int i = 1 ; i<=30 ; i++ )
 92     {
 93         if( ans & (1<<i) )
 94         {
 95             if( flag )
 96             {
 97                 cout << i;
 98                 flag = false;
 99             }
100             else
101             {
102                 cout << " " << i;
103             }
104         }
105     }
106     cout << endl;
107 }
108 
109 int main()
110 {
111     cin.sync_with_stdio(false);
112     int n , m , a , b , c;
113     char op;
114     while( cin >> n >> m && ( n||m ) )
115     {
116         build( 1 , 1 , n );
117         while( m-- )
118         {
119             cin >> op;
120             if( op=='P' )
121             {
122                 cin >> a >> b >> c;
123                 update( 1 , a , b , c );
124             }
125             else
126             {
127                 cin >> a >> b;
128                 ans = 0;
129                 query( 1 , a , b );
130                 solve( );
131             }
132         }
133     }
134     return 0;
135 }
View Code

敲线段树 为什么就那么舒服呢...

原文地址:https://www.cnblogs.com/radical/p/4116669.html