HDU 1698 Just a Hook

该题是一道简单的线段树题目,关键就是区间更新的问题,更新时不要更新到每个节点,而是更新到他们的包括他们的所有节点的父节点就可以了,当有新的更新时,就把父节点的原先的更新更新到子节点,这样就可以尽量保证不必要的重复更新。

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
class Node
{
public:
int l,r,mid;
int value;
};
Node tree[400024];
class Tree
{
public:
void Maketree( int l,int r,int cnt );
void Change( int l,int r,int num,int cnt );
int Sum( int l,int r ,int cnt);
};
void Tree::Maketree(int l,int r,int cnt )
{
if( l == r )
{
tree[cnt].r= tree[cnt].l=tree[cnt].mid = l;
tree[cnt].value = 1;
return ;
}
else
{
tree[cnt].l=l;
tree[cnt].r=r;
tree[cnt].mid = ( l+r )>>1;
tree[cnt].value = 1;
Maketree( l , tree[cnt].mid , cnt*2 );
Maketree( tree[cnt].mid + 1, r ,cnt*2+1 );
}
}
void Tree::Change(int l,int r,int num,int cnt)
{
if( l<=tree[cnt].l&&r>=tree[cnt].r )
{
tree[cnt].value = num;
return;
}
else
{
if( tree[cnt].value == num ) return;
else
{
if( tree[cnt].value>0 )
{
tree[cnt*2].value = tree[cnt*2+1].value = tree[cnt].value;
tree[cnt].value = 0;
}
if( l>tree[cnt].mid ) Change( l , r ,num,cnt*2+1 );
else
{
if( r<=tree[cnt].mid ) Change( l ,r ,num ,cnt*2 );
else
{
Change( l ,tree[cnt].mid,num,cnt*2 );
Change( tree[cnt].mid +1 , r ,num , cnt*2+1 );
}
}
}
}
}
int Tree::Sum( int l,int r,int cnt )
{
if( tree[cnt].value > 0 )
return tree[cnt].value*( tree[cnt].r - tree[cnt].l +1 );
else if( l> tree[cnt].mid ) return Sum( l ,r ,cnt*2+1 );
else
{
if( r <= tree[cnt].mid ) return Sum( l , r , cnt * 2 );
else return Sum( l , tree[cnt].mid, cnt*2 )+Sum( tree[cnt].mid +1 , r ,cnt*2+1 );
}
}
int main( )
{
int Case,n,m,number,l,r,v;
while( scanf( "%d",&Case )==1 )
{
for( int i=1; i<= Case ; i++ )
{
Tree e;
scanf( "%d%d",&number,&m );
e.Maketree(1 , number , 1);
while( m -- )
{
scanf( "%d%d%d",&l,&r,&v );
e.Change(l,r,v,1);
}
printf( "Case %d: The total value of the hook is %d.\n",i,e.Sum( 1,number, 1 ) );
}
}
return 0;
}

 

你可能感兴趣的:(HDU)