(http://poj.org/problem?id=3277)
#include <iostream>
#include <algorithm>
using namespace std;
const int Max = 40000;
// 对象
struct Shadow
{
int b, e, h;
}s[Max];
struct TreeNode
{
int l, r;
int c;
}tree[2*Max*4];
int p[2*Max]; // 离散化向量
long long area;
// 函数
bool cmp_for_s( const Shadow & s1, const Shadow & s2 )
{
return s1.h < s2.h;
}
//-----------------离散化查找-------------------//
int BS( int l, int r, const int key )
{
while( l <= r ) {
int mid = ( l + r ) >> 1;
if( key == p[mid] )
return mid + 1;
else if( key < p[mid] )
r = mid - 1;
else
l = mid + 1;
}
return 0; // 未找到
}
//-----------------线段树操作-------------------//
void Build( const int l, const int r, const int id )
{
tree[id].l = l;
tree[id].r = r;
tree[id].c = 0;
if( r - l == 1 ) return;
int mid = ( l + r ) >> 1;
Build( l, mid, id * 2 );
Build( mid, r, id * 2 + 1 );
}
void Update( const int l, const int r, const int h, const int id )
{
if( tree[id].l == l && tree[id].r == r )
{
tree[id].c = h;
return;
}
if( tree[id].c > 0 )
{
tree[ id*2 ].c = tree[ id*2+1 ].c = tree[id].c;
tree[id].c = 0;
}
int mid = ( tree[id].l + tree[id].r ) >> 1;
if( r <= mid )
Update( l, r, h, id * 2 ); // 注意啊, 注意啊 // 开始写成了 Update( l, mid, ... )
else if( l >= mid )
Update( l, r, h, id * 2 + 1 ); // 同样注意
else
{
Update( l, mid, h, id * 2 );
Update( mid, r, h, id * 2 + 1 );
}
}
void Query( const int id )
{
if( tree[id].c > 0 )
{ // 该死的中间结果溢出,测试时已经发现不对劲了。。
area += ( p[ tree[id].r-1 ] - p[ tree[id].l-1 ] ) * ( long long )tree[id].c;
return;
}
if( tree[id].r - tree[id].l == 1 ) return;
Query( id * 2 );
Query( id * 2 + 1 );
}
//-------------------------end---------------------------//
int main()
{
int N;
scanf( "%d", & N );
int len = 0;
for( int i = 0; i < N; ++ i )
{
scanf( "%d%d%d", & s[i].b, & s[i].e, & s[i].h );
p[ len++ ] = s[i].b;
p[ len++ ] = s[i].e;
}
// 离散化
//::sort( p, p + 2 * N );
::sort( s, s + N, ::cmp_for_s );
// 建树
::Build( 1, 2 * N, 1 );
// 覆盖
for( int i = 0; i < N; ++ i )
{
int l = ::BS( 0, 2 * N - 1, s[i].b );
int r = ::BS( 0, 2 * N - 1, s[i].e );
Update( l, r, s[i].h, 1 );
/*Show( 1 );*/
}
// 遍历树
area = 0;
::Query( 1 ); //::表示该函数是全局作用域
printf( "%lld", area );
return 0;
}