您的位置:首页 > 编程语言 > C语言/C++

线段树

2014-05-07 23:27 423 查看
参考系列:
http://www.cnblogs.com/shuaiwhu/archive/2012/04/22/2464583.html
实现的功能是统计区间出现的数目:(线段树模板的应用)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <ctime>

using namespace std;

typedef int Elemtype;

struct Node{
Elemtype left,right,cover;//区间左右值,覆盖次数
Node *lc;
Node *rc;
};
//建树,区间太大时候需要离散化
Node *Build(int l,int r){
Node *root=new Node;
root->left=l;
root->right=r;
root->lc=NULL;
root->rc=NULL;
root->cover=0;
if(r-l>=1){
int mid=(l+r)>>1;
root->lc=Build(l,mid);
root->rc=Build(mid+1,r);
}
return root;
}

//插入区间[c,d];
void Insert(int c,int d,Node *root){
if(c==root->left && d==root->right){
root->cover++;
return;
}
if(root->left==root->right) return; //无儿子节点,插入返回
int mid=(root->left+root->right)>>1;
if(mid>=d) Insert(c,d,root->lc);
else if(mid<c) Insert(c,d,root->rc);
else{
Insert(c,mid,root->lc);
Insert(mid+1,d,root->rc);
}
}

int ans;

void Search(int l,int r,Node *root){
if(root->cover!=0) ans+=root->cover;
if(root->left==root->right) return;
int mid=(root->left+root->right)>>1;
if(mid>=r) Search(l,r,root->lc);
else if(mid<l) Search(l,r,root->rc);
else{
Search(l,mid,root->lc);
Search(mid+1,r,root->rc);
}
}

int main(){
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
Node *head=new Node();
head=Build(0,30000);
int n,m;
double start=clock();
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
Insert(x,y,head);
}
for(int i=0;i<m;i++){
int x;
scanf("%d",&x);
ans=0;
Search(x,x,head);
printf("%d\n",ans);
}
double end=clock();
fclose(stdin);
fclose(stdout);
printf("%lf\n",end-start);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息