• poj3266一道典型线段树


        因为最近想做的一个东西和区间统计有关,心血来潮玩了下线段树。


       #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;
    }

  • 相关阅读:
    SVN日常使用
    zabbix安装
    shell日常脚本(centos6)
    mysql故障记录
    PHP商品秒杀功能实现思路分析
    Redis
    PHP 实现实时通信一般有两种方式
    FTP DNS SMTP POP3 HTTP HTTPS DHCP DNS SNMP Telnet 端口号
    TCP/UDP/HTTP的区别和联系
    TCP 和 UDP 的区别
  • 原文地址:https://www.cnblogs.com/bester/p/3255776.html
Copyright © 2020-2023  润新知