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 == 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 == 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 }
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 == 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 == 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 }