因为最近想做的一个东西和区间统计有关,心血来潮玩了下线段树。
#include<iostream>
using namespace std;
#define MAXNUMBER 1<<30
class TreeNode
{
public:
TreeNode();
int leftIndex;
int rightIndex;
int maxHeight;
int minHeight;
TreeNode* leftNode;
TreeNode* rightNode;
};
TreeNode::TreeNode()
{
leftIndex=0;
rightIndex=0;
maxHeight=-1;
minHeight=MAXNUMBER;
leftNode=NULL;
rightNode=NULL;
}
class SegmentTree
{
public:
SegmentTree();
int cowNumber;//node nubmer
TreeNode *treeRoot;
int heightArray[50005];
void InitializeTree();
void FindTreeMinAndMaxValue(TreeNode *tNode);
void QueryTree(TreeNode *tNode,int lIndex,int rIndex,int& min,int& max);
};
SegmentTree::SegmentTree()
{
treeRoot=NULL;
}
void SegmentTree::InitializeTree()
{
treeRoot=new TreeNode();
treeRoot->leftIndex=0;
treeRoot->rightIndex=this->cowNumber-1;
//Compare the Left Child and Right Child result
FindTreeMinAndMaxValue(treeRoot);
return;
}
void SegmentTree::FindTreeMinAndMaxValue(TreeNode *tNode)
{
//See if the node exists.
if(tNode->leftIndex==tNode->rightIndex)
{
tNode->maxHeight=this->heightArray[tNode->leftIndex];
tNode->minHeight=this->heightArray[tNode->rightIndex];
return;
}
//Find left child min and max value
tNode->leftNode=new TreeNode();
tNode->leftNode->leftIndex=tNode->leftIndex;
tNode->leftNode->rightIndex=(tNode->leftIndex + tNode->rightIndex)/2 ;
if(tNode->leftNode->leftIndex <= tNode->leftNode->rightIndex)//The segmen exists
{
FindTreeMinAndMaxValue(tNode->leftNode);
}
else
{
tNode->leftNode->minHeight=MAXNUMBER;
tNode->leftNode->maxHeight=-1;
}
//Find right child min and max value
tNode->rightNode=new TreeNode();
tNode->rightNode->leftIndex=(tNode->leftIndex+tNode->rightIndex)/2 + 1;
tNode->rightNode->rightIndex=tNode->rightIndex;
if(tNode->rightNode->leftIndex <= tNode->rightNode->rightIndex)//The segmen exists
{
FindTreeMinAndMaxValue(tNode->rightNode);
}
else
{
tNode->rightNode->minHeight=MAXNUMBER;
tNode->rightNode->maxHeight=-1;
}
//merge the resultt
tNode->maxHeight=(tNode->leftNode->maxHeight>tNode->rightNode->maxHeight)?tNode->leftNode->maxHeight:tNode->rightNode->maxHeight;
tNode->minHeight=(tNode->leftNode->minHeight<tNode->rightNode->minHeight)?tNode->leftNode->minHeight:tNode->rightNode->minHeight;
return;
}
void SegmentTree::QueryTree(TreeNode *tNode,int lIndex,int rIndex,int& minHeight,int& maxHeight)
{
if( tNode->leftIndex==lIndex && tNode->rightIndex==rIndex)
{
minHeight=tNode->minHeight;
maxHeight=tNode->maxHeight;
return;
}
//See left child
int leftMinHeight=MAXNUMBER;
int leftMaxHeight=-1;
if(tNode->leftNode->rightIndex >= lIndex)//Interact with left child
{
if(tNode->leftNode->rightIndex < rIndex)//the range interact with left child partly
{
QueryTree(tNode->leftNode,lIndex,tNode->leftNode->rightIndex,leftMinHeight,leftMaxHeight);
}
else//left child conclude the range
{
QueryTree(tNode->leftNode,lIndex,rIndex,leftMinHeight,leftMaxHeight);
}
}
//See right child
int rightMinHeight=MAXNUMBER;
int rightMaxHeight=-1;
if(tNode->rightNode->leftIndex <= rIndex)//Interact with right child
{
if(tNode->rightNode->leftIndex > lIndex)//the range interacts with the right child partly
{
QueryTree(tNode->rightNode,tNode->rightNode->leftIndex,rIndex,rightMinHeight,rightMaxHeight);
}
else//the right child conclude the range totally
{
QueryTree(tNode->rightNode,lIndex,rIndex,rightMinHeight,rightMaxHeight);
}
}
//Merge the result
minHeight=(leftMinHeight<rightMinHeight)?leftMinHeight:rightMinHeight;
maxHeight=(leftMaxHeight>rightMaxHeight)?leftMaxHeight:rightMaxHeight;
return;
}
int main()
{
SegmentTree sTree;
int answerArray[200002];
int N,Q;
scanf("%d%d",&N,&Q);
sTree.cowNumber=N;
for(int i=0;i<N;i++)
{
scanf("%d",&sTree.heightArray[i]);
}
sTree.InitializeTree();
for(int i=0;i<Q;i++)
{
int minHeight=MAXNUMBER,maxHeight=-1;
int lIndex,rIndex;
scanf("%d%d",&lIndex,&rIndex);
lIndex--;
rIndex--;
sTree.QueryTree(sTree.treeRoot,lIndex,rIndex,minHeight,maxHeight);
answerArray[i]=maxHeight-minHeight;
}
for(int i=0;i<Q;i++)
{
printf("%d\n",answerArray[i]);
}
return 0;
}