线段树模板一

来源:互联网 发布:淘宝男装原创品牌 编辑:程序博客网 时间:2024/04/30 00:59
//线段树模板一   链表版//功能:在自然数,且所有的数不大于30000的范围内讨论一个问题:现在已知n条线段,把端点//依次输入告诉你,然后有m个询问,每个询问输入一个点,要求这个点在多少条线段上出现#include <iostream>#include <cstring>#include <cstdio>using namespace std;struct treel{    int left,right;   //左端点 右端点    int num;          //记录这条线段出现过多少次    struct treel *lc,*rc;};struct treel *build(int l,int r){    treel *root= new treel;    root->left=l;root->right=r;    root->num=0;    int mid=(root->left+root->right)>>1;    if(l!=r)    //成立表示此端点不是叶子节点    {        root->lc=build(l,mid);        root->rc=build(mid+1,r);    }    return root;}void Insert(int c,int d,treel *root){    if(c==root->left&&d==root->right)   //结果匹配    {        root->num++;        return ;    }    if(c==d)   return ;   //到达最低段    int mid = (root->left+root->right)>>1;    if(c>mid)  Insert(c,d,root->rc);   //如果左端点比中点还大,则要插到右子树中去    else if(d<=mid)   Insert(c,d,root->lc);    else { Insert(c,mid,root->lc);  Insert(mid+1,d,root->rc); }}int sum=0;    //标记要查询的线段出现过多少次//查询过程和插入过程相似void Find(int c,int d,treel *root){    if(c==root->left&&d==root->right)    {        sum+=root->num;        return ;    }    if(root->left==root->right)   return ;    int mid = (root->left+root->right)>>1;    if(c>mid)  Find(c,d,root->rc);    else if(d<=mid)  Find(c,d,root->lc);    else { Find(c,mid,root->lc); Find(mid+1,d,root->rc);  }    sum+=root->num;}//层序遍历输出void levalorder(struct treel *root){struct treel *queue[100];int rear=0,front=-1;if(!root)return ;queue[rear]=root;while(front!=rear){front++;printf("%d ",queue[front]->num);//将左孩子结点入队if(queue[front]->lc){rear++;queue[rear]=queue[front]->lc;}//将右孩子节点入队if(queue[front]->rc){rear++;queue[rear]=queue[front]->rc;}}}int main(){    struct treel *root=build(0,7);    Insert(2,5,root);    Insert(4,6,root);    Insert(0,7,root);    sum=0;    Find(2,3,root);   cout<<sum<<endl;    //levalorder(root);    return 0;}

0 0
原创粉丝点击