HDU 3016 Man Down
2012-02-28 15:22
302 查看
该题是一道,成段更新,单点查询(简单线段树+简单DP),这个题与http://poj.org/problem?id=1436思想差不多,这里我就不重复了,这里就是要处理最大值的问题也就是DP;
我有的方法就是以该条边的两个端点往下搜索,如果下面有可见的边,选择值的那条边,然后再进行更新;
我有的方法就是以该条边的两个端点往下搜索,如果下面有可见的边,选择值的那条边,然后再进行更新;
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; class Node { public: int l ,r , sum,cover; }; Node tree[2000024]; class segment { public: int x1,x2,y,value; }; segment seg[150024]; bool cmp( segment a, segment b ) { return a.y < b.y; } class Tree { public: void Maketree( int l , int r, int cnt ); void Update( int l , int r ,int cnt, int id, int sum ); int Max( int a, int b ) { return a>b?a:b; } int Query( int cnt,int num ); }; void Tree::Maketree( int l , int r , int cnt ) { tree[cnt].l = l ; tree[cnt].r = r; tree[cnt].cover = -1; tree[cnt].sum = 0; if( l == r ) return ; int mid = ( l + r )>>1; Maketree( l , mid , cnt*2 ); Maketree( mid + 1 , r , cnt*2+1 ); } void Tree::Update( int l , int r , int cnt , int id ,int sum) { if( l<=tree[cnt].l&&r>=tree[cnt].r ) { tree[cnt].sum=sum+seg[id].value; tree[cnt].cover = id; // printf( "l==%d r==%d sum==%d\n",tree[cnt].l ,tree[cnt].r,tree[cnt].sum); return ; } else { if( tree[cnt].cover !=-1 )//向下进行更新 { tree[cnt*2].cover = tree[cnt*2+1].cover = tree[cnt].cover; tree[cnt].cover = -1; tree[cnt*2].sum = tree[cnt*2+1].sum = tree[cnt].sum; } int mid = ( tree[cnt].r + tree[cnt].l )>>1; if( l > mid ) Update( l ,r ,cnt*2+1, id ,sum ); else { if( r <= mid ) Update( l ,r ,cnt * 2 , id ,sum ); else { Update( l ,mid , cnt*2 , id ,sum ); Update( mid + 1 , r , cnt*2+1 , id ,sum ); } } } } int Tree::Query( int cnt , int num ) { if( tree[cnt].cover!=-1 ) { // printf( "%d %d\n",tree[cnt].sum,num ); return tree[cnt].sum; } int mid = ( tree[cnt].l + tree[cnt].r )>>1; if( num>mid ) return Query( cnt*2+1 , num ); else return Query( cnt*2 , num ); return 0; } int main( ) { int n; while( scanf( "%d",&n )==1 ) { Tree e; e.Maketree( 0,200000 , 1 ); for( int i = 0; i < n ; i++ ) { scanf( "%d%d%d%d",&seg[i].y,&seg[i].x1,&seg[i].x2,&seg[i].value ); seg[i].x1 *= 2; seg[i].x2 *= 2; } sort( seg , seg+n , cmp ); //对Y进行排序 for( int i = 0 ; i < n-1 ; i++ ) { int sum = e.Max( e.Query( 1 , seg[i].x1 ),e.Query( 1 , seg[i].x2 ) );//对两个端点进行选择最大值 e.Update( seg[i].x1 , seg[i].x2, 1 , i , sum );//进行更新 } int sum = 100 + e.Max( e.Query( 1 , seg[n-1].x1 ),e.Query( 1 , seg[n-1].x2 ) ) +seg[n-1].value;//最后一个段进行处理 printf( sum>0?"%d\n":"-1\n",sum); } return 0; }
相关文章推荐
- hdu 3016 Man Down 线段树+dp
- hdu 3016 Man Down(线段树)
- hdu 3016 Man Down (线段树 + dp)
- HDU 3016 Man Down (线段树+dp)
- hdu 3016 Man Down(线段树)
- hdu-3016-Man Down(线段树)
- hdu 3016 Man Down
- HDU 3016 Man Down(线段树)
- HDU-3016:Man Down(线段树+DP)
- hdu 3016 Man Down(成段更新,单点查询)
- HDU 3016 Man Down
- hdu 3016 Man Down
- HDU 3016 Man Down (线段树+dp)
- hdu 3016 Man Down
- HDU 3016 Man Down (线段树+dp)
- HDU 3016 Man Down(线段树区间单点查询+DP)
- hdu(3016) Man Down(线段树查询更新+dp)
- hdu 3016 Man Down(线段树)
- HDU 3016 Man Down(线段树 + DP)
- hdu 3016 Man Down(线段树区间更新+dp)