线段树;
// 离散化的线段树;
#include < stdio.h >
#include < algorithm >
#include < memory.h >
using namespace std;
![](/Images/OutliningIndicators/None.gif)
const int MAX = 1100000 ;
int p[ 3 * MAX];
int b[MAX];
int c[MAX];
int q[ 3 * MAX];
int Min[MAX];
int Max[MAX];
class IntervalTree
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
public :
int n;
IntervalTree();
void set ( int x);
int InsOrDel( int x, int test);
int FMAX();
int FMIN();
int Find( int x);
} ;
IntervalTree::IntervalTree()
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
memset(p, 0 , sizeof (p));
}
void IntervalTree:: set ( int m)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
n = m;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//**/ /**//* initial n to the smallest number;
int k=Insert(1,1);
for(int i=1;i<=k;i*=2)
p[i]=n;
*/
}
int IntervalTree::InsOrDel( int x, int test) // test=1,add;test=0,delete;
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
int left = 0 ,right = n;
int k = 1 ;
int mid;
while (left < right)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
mid = (left + right) >> 1 ;
if (test > 0 )
p[k] ++ ;
else p[k] -- ;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (x <= c[mid])
{
k <<= 1 ;
right = mid;
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
else
{
k <<= 1 ;
k ++ ;
left = mid + 1 ;
}
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (test > 0 )
{
p[k] ++ ;
q[k] = x;
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
else
{
p[k] -- ;
}
return k;
}
int IntervalTree::FMAX() // find the max;
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
int k;
k = 1 ;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (p[ 2 * k] > 0 || p[ 2 * k + 1 ] > 0 )
{
if (p[ 2 * k + 1 ] > 0 )k = 2 * k + 1 ;
else k = 2 * k;
}
return q[k];
}
int IntervalTree::FMIN() // find the min;
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
int k;
k = 1 ;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (p[ 2 * k] > 0 || p[ 2 * k + 1 ] > 0 )
{
if (p[ 2 * k] > 0 )k = 2 * k;
else k = 2 * k + 1 ;
}
return q[k];
}
int IntervalTree::Find( int t) // Find the index of t;
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
int left = 1 ,right = n;
int mid;
int k = 1 ;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (left < right)
{
mid = (left + right) >> 1 ;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (t <= p[k])
{
k <<= 1 ;
right = mid;
}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
else
{
t -= p[k];
k <<= 1 ;
k ++ ;
left = mid + 1 ;
}
}
mid = (left + right) >> 1 ;
if (p[mid] == t) return mid;
else return - 1 ; // t isn't in the tree;
}
int main()
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
IntervalTree a;
int l,i;
int max,min;
int k,n;
int m;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
while (scanf( " %d%d " , & n, & k) != EOF)
{
memset(p, 0 , sizeof (p));
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for (i = 0 ;i < n;i ++ )
{
scanf( " %d " ,b + i);
c[i] = b[i];
}
sort(c,c + n);
// 离散化,相同的点合并;
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for (i = 0 ,m = 0 ;i < n;i ++ ,m ++ )
{
while (i < n - 1 && c[i] == c[i + 1 ])i ++ ;
c[m] = c[i];
}
a. set (m - 1 ); // initial;
return 0 ;
}