非递归线段树专题
Posted yijiull
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了非递归线段树专题相关的知识,希望对你有一定的参考价值。
学习了自底向上的非递归线段树,深感精妙!!
大牛的博客:http://blog.csdn.net/zearot/article/details/48299459
张坤玮---统计的力量
The Union of k-Segments
题意:求被覆盖k次及以上的点或者线段。
看到别人直接用扫描线写的,更方便一些。
不过拿来练习线段树也不错。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn=1000010; 4 int cn,c[maxn<<1]; //离散化 5 int n,k,l[maxn],r[maxn]; 6 void discrete(){ 7 sort(c+1,c+1+cn); 8 int I=1; 9 for(int i=2;i<=cn;i++) if(c[i]!=c[i-1]) c[++I]=c[i]; 10 cn=I; 11 } 12 int getid(int x){ 13 int L=1,R=cn,m; 14 while(L<=R){ 15 m=(L+R)>>1; 16 if(c[m]==x) return m; 17 if(c[m]<x) L=m+1; 18 else R=m-1; 19 } 20 } 21 int N; 22 int add[maxn<<3],p[maxn<<3]; 23 void build(int n){ 24 N=1;while(N<n+2) N<<=1; 25 memset(add,0,sizeof(add)); 26 memset(p,0,sizeof(p)); 27 } 28 void update(int L,int R){ 29 for(int s=N+L-1,t=N+R;s^t^1;s>>=1,t>>=1){ 30 if(~s&1) ++add[s^1]; 31 if( t&1) ++add[t^1]; 32 } 33 for(int s=N+L-1,t=N+R+1;s^t^1;s>>=1,t>>=1){ 34 if(~s&1) ++p[s^1]; 35 if( t&1) ++p[t^1]; 36 } 37 } 38 void pushdown(){ 39 for(int i=1;i<N;i++){ 40 add[i<<1]+=add[i]; 41 add[i<<1|1]+=add[i]; 42 p[i<<1]+=p[i]; 43 p[i<<1|1]+=p[i]; 44 } 45 } 46 47 int main(){ 48 while(scanf("%d%d",&n,&k)!=EOF){ 49 for(int i=cn=0;i<n;i++){ 50 scanf("%d%d",&l[i],&r[i]); 51 c[++cn]=l[i]; 52 c[++cn]=r[i]; 53 } 54 discrete(); 55 build(cn); 56 for(int i=0;i<n;i++){ 57 update(getid(l[i]),getid(r[i])); 58 } 59 pushdown(); //下推!! 60 //统计 61 int flag=0,cnt=0; 62 for(int i=1;i<=cn;i++){ 63 if(add[N+i]>=k){ 64 if(!flag){ //左端点 65 l[++cnt]=c[i]; 66 flag=1; 67 } 68 }else{ 69 if(flag){ //右端点 70 r[cnt]=c[i]; 71 flag=0; 72 }else { 73 if(p[N+i]>=k){ 74 l[++cnt]=c[i]; 75 r[cnt]=c[i]; 76 } 77 } 78 } 79 } 80 printf("%d\n",cnt); 81 for(int i=1;i<=cnt;i++){ 82 printf("%d %d\n",l[i],r[i]); 83 } 84 } 85 return 0; 86 }
以上是关于非递归线段树专题的主要内容,如果未能解决你的问题,请参考以下文章