营业额统计

[HNOI2002]营业额统计 一个丰富的OI题库 http://www.zybbs.org/JudgeOnline/ 这题其实很一道很裸的Splay_tree,每次插入一个节点,我们就把它旋转到根节点,然后把最靠近这个节点的两个值(左子树的最大值,右子树的最小值)找出来比较一下就行了,对于Splay_tree  我就不累叙了;

#include<iostream>
#include<cstdio>
#include<string>
#include<cstdlib>
using namespace std;
class Tree
{
public:
int num;
int cnt;
Tree *lchild,*rchild,*father;
Tree( int n = 0 ){ num = n; lchild = rchild = father =NULL; cnt= 0;}
};
class Splay
{
private:
Tree *root;
int count;
public:
Splay( ){ root = NULL ; count =0; }
void L_Romate( Tree *&x );
void R_Romate( Tree *&x );
void splay( Tree *&x );
void Insert( int &number );
int findMax( Tree *T );
int findMin( Tree *T );
Tree *find( int& number ,Tree *T);
int opt( int &number );
int min( int a,int b )
{ return a<b? a:b;}
};
void Splay::L_Romate( Tree *&x )
{
Tree *y = x -> father , *z = y->father;
y -> rchild = x -> lchild;
x -> lchild = y;
if( y -> rchild ) y -> rchild -> father = y;
y->father = x;
x -> father = z;
if( z )
{
if( z->lchild == y ) z->lchild = x;
else z -> rchild = x;
}
}
void Splay::R_Romate( Tree *&x )
{
Tree *y = x -> father ,*z = y -> father;
y -> lchild = x -> rchild ;
x -> rchild = y;
if( y -> lchild ) y->lchild -> father = y;
x -> father = z;y -> father = x;
if( z )
{
if( z -> lchild == y ) z -> lchild = x;
else z -> rchild = x;
}
}
void Splay::splay( Tree *&x )
{
while( x -> father )
{
Tree *y = x -> father ,*z = y -> father;
if( !z )
{
if( y->lchild == x ) R_Romate( x );
else L_Romate( x );
}
else
{
if( z -> lchild == y&& y->lchild == x )
{
R_Romate( y );
R_Romate( x );
}
else
{
if( z -> rchild == y && y->rchild ==x )
{
L_Romate( y );
L_Romate( x );
}
else
{
if( z -> rchild == y && y -> lchild == x )
{
R_Romate( x );
L_Romate( x );
}
else
{
L_Romate( x );
R_Romate( x );
}
}
}
}
}
root = x;
root -> father = NULL;
}
void Splay::Insert( int &number )
{
if( !count )
{
root = new Tree( number );
}
else
{
Tree *p = find( number ,root ),*q;
if( p -> num == number )
{
p -> cnt++;
q = p;
}
else
{
if( p -> num > number )
{
p->lchild = new Tree( number );
p->lchild->father = p;
q = p->lchild ;
}
else
{
p -> rchild = new Tree( number );
p -> rchild -> father = p;
q = p -> rchild;
}
}
splay( q );
}
count++;
}
Tree *Splay::find( int &number,Tree *T )
{
if( T && T -> num == number ) return T;
else
{
if( T -> num > number && T -> lchild )
return find( number , T -> lchild );
else
{
if( T -> num < number && T -> rchild )
return find( number , T -> rchild );
else return T;
}
}
}
int Splay::findMax( Tree *T )
{
if( T && T->rchild )
return findMax( T -> rchild );
if( T )
return T->num;
return 0x7fffffff;

}
int Splay::findMin( Tree *T )
{
if( T && T->lchild )
return findMin( T->lchild );
if( T )
return T->num;
return 0x7fffffff;
}

int Splay::opt( int &number )
{

if( root->lchild == NULL && root->rchild == NULL )
return abs(root->num);
if( root->cnt ) return 0;
int a,b,c = root->num;
// printf( "root = %d\n",root->num );
a = findMax( root->lchild );
b = findMin( root->rchild );
// printf( "%d %d\n",a,b );
return min( abs(c-a),abs(c-b) );

}
int main( )
{
int n,m,sum;
while( scanf( "%d" ,&n )==1 )
{
Splay rt;
sum = 0;
for( int i=0 ; i< n; i++ )
{
m=0;
scanf( "%d" ,&m );
rt.Insert( m );
sum += rt.opt( m );
// printf( "sum==%d\n",sum );
}
printf( "%d\n",sum );
}
return 0;
}

 

你可能感兴趣的:(统计)