线段树 (区间覆盖模板)
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
相关文章推荐
- linux内实践核分析模块
- 使用spring dataSource的几种方式
- 总结const的用法
- 【Linux】vim的配置
- 如何利用dex2jar反编译APK及代码混淆
- dll文件32位64位检测工具以及Windows文件夹SysWow64的坑(很详细,还有自动动手编程探测dll)
- 最大化平均值
- Thread
- 由浅入深全面剖析ThreadLocal
- 关于saltstack下 sls文件编写的一点收获
- poj 2342 anniversary party
- JAVA NIO技术(中)
- JAVA NIO技术(下)
- LeetCode:Delete Node in a Linked List
- 【数据库】安装和配置Oracle客户端
- ubuntu安装jdk-8u45
- POJ3625 Building Roads
- OpenGL程序无法启动此应用程序,因为计算机中丢失glut32.dll
- 在VMware上安装CentOS-6.5 minimal - 安装VMware Tools
- cron表达式