http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3299

zoj 月赛的时候没有解出来,当时以为是二维线段树,由于二维的一道都没写过,所以这题被我放弃了,后来看了别人的解题报告,原来是一维的。。。

先按高度给line从小到大排序,然后按顺序插入木板,后面可以覆盖前面的,然后再在线段树上插入砖块,用一个num域来表示这一段有多少砖块,然后最后统计的时候把所有的标记下传到叶子节点再算就成。由于好久没写线段树,写的时候思维有点混乱,并且使用了复制粘贴,导致两句代码有问题,一直没有发现,一共WA了7次(-_-|||)

  1  #include < iostream >
  2 #include<algorithm>
  3  #define  MAXN 100010
  4  using   namespace  std;
  5  struct  NODE
  6  {
  7       int  l,r;
  8       int  ID,num; //  分别记录第cnt条木板 和 砖块数量
  9  }tree[MAXN * 12 ];
 10  struct  Board
 11  {
 12       int  l,r,h,ID;
 13  };
 14  struct  Brick
 15  {
 16       int  l,r;
 17  };
 18  Brick bri[MAXN];
 19  Board ban[MAXN];
 20  int  x[MAXN * 4 ];
 21  int  n,m,len;
 22  long   long  ans[MAXN];
 23 
 24  bool  compare(  const  Board  & a,  const  Board  & b )
 25  {
 26       return  a.h < b.h;
 27  }
 28 
 29  int  find(  int  n )
 30  {
 31       int  l = 0 ,r = len - 1 ,mid;
 32       while ( l <= r )
 33      {
 34          mid = (l + r) >> 1 ;
 35           if ( x[mid] == n ) return  mid;
 36           else   if ( x[mid] < n )l = mid + 1 ;
 37           else  r = mid - 1 ;
 38      }
 39  }
 40 
 41  void  make_tree(  int  v,  int  l,  int  r )
 42  {
 43       int  mid;
 44      tree[v].l = l,tree[v].r = r,tree[v].ID = 0 ,tree[v].num = 0 ;
 45       if ( l + 1   !=  r )
 46      {
 47          mid = (l + r) >> 1 ;
 48          make_tree( v << 1 , l, mid );
 49          make_tree( (v << 1 ) + 1 , mid, r );
 50      }
 51  }
 52 
 53  void  lisanhua( )
 54  {
 55       int  i,k = len;
 56      sort( x, x + len );
 57      len = 1 ;
 58       for ( i = 1 ; i < k; i ++  )
 59           if ( x[i]  !=  x[i - 1 ] )x[len ++ ] = x[i];
 60       for ( i = 1 ; i <= n; i ++  )
 61      {
 62          bri[i].l = find( bri[i].l );
 63          bri[i].r = find( bri[i].r );
 64      }
 65       for ( i = 1 ; i <= m; i ++  )
 66      {
 67          ban[i].l = find( ban[i].l );
 68          ban[i].r = find( ban[i].r );
 69      }
 70  }
 71 
 72  void  insertboard(  int  v,  int  l,  int  r,  int  ID )
 73  {
 74       int  mid;
 75       if ( tree[v].l == &&  tree[v].r == r )
 76      {
 77          tree[v].ID = ID;
 78           return  ;
 79      }
 80       if ( tree[v].ID )
 81      {
 82           if ( tree[v].l + 1   !=  tree[v].r )
 83          {
 84              tree[v << 1 ].ID = tree[v].ID;
 85              tree[(v << 1 ) + 1 ].ID = tree[v].ID;
 86              tree[v].ID = 0 ;
 87          }
 88      }
 89       mid = (tree[v].l + tree[v].r) >> 1 ;
 90       if ( r <= mid )insertboard( v << 1 , l, r, ID );
 91       else   if ( l >= mid )insertboard( (v << 1 ) + 1 , l, r, ID );
 92       else
 93      {
 94          insertboard( v << 1 , l, mid, ID );
 95          insertboard( (v << 1 ) + 1 , mid, r, ID );
 96      }
 97  }
 98 
 99  void  insertbrick(  int  v,  int  l,  int  r )
100  {
101       int  mid;
102       if ( tree[v].l == &&  tree[v].r == r )
103      {
104          tree[v].num ++ ;
105           // if( tree[v].l+1==tree[v].r )return ;
106           // tree[v<<1].num+=tree[v].num;
107           // tree[(v<<1)+1].num+=tree[v].num;
108           // tree[v].num=0;
109           return  ;
110      }
111      mid = (tree[v].l + tree[v].r) >> 1 ;
112       if ( r <= mid )insertbrick( v << 1 , l, r );
113       else   if ( l >= mid )insertbrick( (v << 1 ) + 1 , l, r );
114       else  
115      {
116          insertbrick( v << 1 , l, mid );
117          insertbrick( (v << 1 ) + 1 , mid, r );
118      }
119  }
120 
121  void  query(  int  v,  int  l,  int  r )
122  {
123       int  mid;
124       if ( tree[v].l + 1 == tree[v].r )
125      {
126          ans[tree[v].ID] = ans[tree[v].ID] + ( long   long )(x[tree[v].r] - x[tree[v].l]) * ( long   long )tree[v].num;
127           return  ;
128      }
129       if ( tree[v].ID )
130      {
131          tree[v << 1 ].ID = tree[v].ID;
132          tree[(v << 1 ) + 1 ].ID = tree[v].ID;
133          tree[v].ID = 0 ;
134      }
135       if ( tree[v].num )
136      {
137          tree[v << 1 ].num += tree[v].num;
138          tree[(v << 1 ) + 1 ].num += tree[v].num;
139          tree[v].num = 0 ;
140      }
141      mid = (tree[v].l + tree[v].r) >> 1 ;
142       if ( r <= mid )query( v << 1 , l, r );
143       else   if ( l >= mid ) query( (v << 1 ) + 1 , l, r );
144       else  
145      {
146          query( v << 1 , l, mid );
147          query( (v << 1 ) + 1 , mid, r );
148      }
149  }
150 
151  void  solve( )
152  {
153       int  i;
154      sort( ban + 1 , ban + m + 1 , compare ); 
155      make_tree(  1 0 , len - 1  );
156       for ( i = 1 ; i <= m; i ++  )
157          insertboard(  1 , ban[i].l, ban[i].r, ban[i].ID );
158       for ( i = 1 ; i <= n; i ++  )
159          insertbrick(  1 , bri[i].l, bri[i].r );
160      memset( ans,  0 sizeof (ans) );
161      query(  1 0 , len - 1  );
162       for ( i = 1 ; i <= m; i ++  )
163          printf( " %lld\n " ,ans[i]);
164      printf( " \n " );
165  }
166 
167  int  main( )
168  {
169       int  i;
170       while ( scanf( " %d%d " , & n, & m)  !=  EOF )
171      {
172          len = 0 ;                         
173           for ( i = 1 ; i <= n; i ++  )
174          {
175              scanf( " %d%d " , & bri[i].l, & bri[i].r);
176              x[len ++ ] = bri[i].l;
177              x[len ++ ] = bri[i].r;
178          } 
179           for ( i = 1 ; i <= m; i ++  )
180          {
181              scanf( " %d%d%d " , & ban[i].l, & ban[i].r, & ban[i].h);
182              x[len ++ ] = ban[i].l;
183              x[len ++ ] = ban[i].r;
184              ban[i].ID = i;            
185          }
186          lisanhua( ); 
187          solve( );       
188      }
189       return   0 ;
190  }