您的位置:首页 > 其它

线段树 (区间覆盖模板)

2016-05-26 20:19 295 查看

线段树

  线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。
  对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2+1,b]。因此线段树是平衡二叉树,最后的子节点数目为N,即整个线段区间的长度。
  使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(logN)。而未优化的空间复杂度为2N,因此有时需要离散化让空间压缩。

题目链接: http://acm.zzuli.edu.cn/zzuliacm/problem.php?id=1877
代码:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
#define for0(i, n) for(int i=0; i<(n); ++i)
#define for1(i,a,n) for(int i=(a);i<=(n);++i)
#define for2(i,a,n) for(int i=(a);i<(n);++i)
#define for3(i,a,n) for(int i=(a);i>=(n);--i)
#define for4(i,a,n) for(int i=(a);i>(n);--i)
#define CC(i,a) memset(i,a,sizeof(i))
#define LL long long
#define MOD 1000000007
#define inf 0x3f3f3f3f

#define EPS 1e-6
#define N 100010
#define lson p<<1
#define rson p<<1|1

struct num
{
int l,r;
}a
;
int v
;

struct node
{
int l,r,x;
int mid(){
return (l+r)/2;
}
int len(){
return (r-l+1);
}
}tree[N<<2];

void buildtree(int p,int L,int R)
{
tree[p].l=L;
tree[p].r=R;
tree[p].x=0;
if(L==R)
return ;

buildtree(lson,L,tree[p].mid());
buildtree(rson,tree[p].mid()+1,R);
}

void update(int p,int L,int R)
{
if(tree[p].l==L && tree[p].r==R){
tree[p].x++;
return ;
}
if(R <= tree[p].mid())
update(lson,L,R);
else if(L > tree[p].mid())
update(rson,L,R);
else{
update(lson,L,tree[p].mid());
update(rson,tree[p].mid()+1,R);
}
}

void up(int p,int L,int R)
{
if(L==R)
return ;
tree[lson].x += tree[p].x;
tree[rson].x += tree[p].x;

up(lson,L,tree[p].mid());
up(rson,tree[p].mid()+1,R);

tree[p].x = min(tree[lson].x,tree[rson].x);
}

int query(int p,int L,int R)
{
if(tree[p].l==L && tree[p].r==R)
return tree[p].x;
if(R <= tree[p].mid())
return query(lson,L,R);
else if(L > tree[p].mid())
return query(rson,L,R);
else
return min(query(lson,L,tree[p].mid()),query(rson,tree[p].mid()+1,R));

}

int main()
{
int t;
scanf("%d",&t);
while(t--){
int n,m,k=0,ans;
scanf("%d%d",&n,&m);
memset(a,0,sizeof(a));
memset(v,0,sizeof(v));
buildtree(1,1,n);

for(int i=1; i<=m; i++){
scanf("%d%d",&a[i].l,&a[i].r);
update(1,a[i].l,a[i].r);
}

up(1,1,n);

for(int i=1; i<=m; i++){
ans=query(1,a[i].l,a[i].r);
if(ans >= 2)
v[k++] = i;
}
printf("%d\n", k);
for(int i=0; i<k; i++)
printf("%d%c", v[i], i==k-1?'\n':' ');
}
return 0;
}


另外的版本: https://hrbust-acm-team.gitbooks.io/acm-book/content/data_structure/ds_part3.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: