标签:style blog http color os io 数据 for
可持久化数据结构(Persistent data structure)就是利用函数式编程的思想使其支持询问历史版本、同时充分利用它们之间的共同数据来减少时间和空间消耗。
所以这里讲的可持久化线段树也叫函数式线段树(又叫主席树……因为先驱就是fotile主席Orz……)。
先了解一下主席树
http://seter.is-programmer.com/posts/31907.html 很详细的介绍了函数式线段树(主席树)。
主席树其实就是很多棵线段树,由于每次更新只需要更新logN个节点,所以主席树的内存不用到达N*N的级别,只需要NlogN级别。。
每次更新的时候都新建一个节点,然后递归下去,更新了logN个节点,其他的节点就与之前建的线段树一起共用。。
http://acm.hdu.edu.cn/showproblem.php?pid=4417 hdu4417 Super Mario
题意:给定一段区间每个点有个高度。在m次询问中每次给出左右端点和可以到达的高度,统计有多少个是小于到达高度
做法:主席树 + 离散化。。输入比较大,所以需要离散化。。tot统计总的节点个数,结构体的sum是统计出现的数的个数,每次询问[l, r] x的时候,就在第r棵线段树-第l-1棵线段树( 相当于[l, r]区间的数 ) 里面找小于等于x的个数。。建议先看代码,看不懂再去在主席树的介绍,这样重复的看。。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<string> 5 #include<algorithm> 6 #include<queue> 7 #include<cmath> 8 #include<vector> 9 10 using namespace std; 11 12 #define mnx 100050 13 #define ll long long 14 #define mod 1000000007 15 #define inf 223372036854775807 16 #define eps 1e-10 17 #define Pi acos(-1.0); 18 #define lson l, m, rt << 1 19 #define rson m+1, r, rt << 1 | 1 20 21 ll a[mnx], b[mnx]; 22 int root[mnx], tot; 23 struct node{ 24 int ls, rs, sum; 25 }p[mnx*20]; 26 int build( int l, int r ){ 27 int rt = tot++; 28 p[rt].sum = 0; 29 if( l == r ) return rt; 30 int m = ( l + r ) >> 1; 31 p[rt].ls = build( l, m ); 32 p[rt].rs = build( m + 1, r ); 33 return rt; 34 } 35 int update( int x, int v, int i, int l, int r ){ 36 int rt = tot++; 37 p[rt] = p[i]; 38 p[rt].sum += v; 39 if( l == r ) return rt; 40 int m = ( l + r ) >> 1; 41 if( x <= m ) p[rt].ls = update( x, v, p[i].ls, l, m ); 42 else p[rt].rs = update( x, v, p[i].rs, m + 1, r ); 43 return rt; 44 } 45 int query( int i, int j, int k, int l, int r ){ 46 if( l == r ) return p[i].sum - p[j].sum; 47 int ret = 0, m = ( l + r ) >> 1; 48 if( k > m ){ 49 ret += ( p[p[i].ls].sum - p[p[j].ls].sum ); 50 ret += query( p[i].rs, p[j].rs, k, m + 1, r ); 51 } 52 else{ 53 ret += query( p[i].ls, p[j].ls, k, l, m ); 54 } 55 return ret; 56 } 57 int main(){ 58 int cas, cnt = 1; 59 scanf( "%d", &cas ); 60 while( cas-- ){ 61 tot = 0; 62 int n, m; 63 scanf( "%d %d", &n, &m ); 64 for( int i = 1; i <= n; i++ ){ 65 scanf( "%I64d", &a[i] ); 66 b[i] = a[i]; 67 } 68 sort( b + 1, b + 1 + n ); 69 int tmp = unique( b + 1, b + 1 + n ) - b - 1; 70 tmp++, b[tmp] = inf; 71 root[0] = build( 1, tmp ); 72 for( int i = 1; i <= n; i++ ){ 73 int k = lower_bound( b + 1, b + 1 + tmp, a[i] ) - b; 74 root[i] = update( k, 1, root[i-1], 1, tmp ); 75 } 76 printf( "Case %d:\n", cnt++ ); 77 while( m-- ){ 78 int l, r; ll v; 79 scanf( "%d %d %I64d", &l, &r, &v ); 80 l++, r++; 81 int k = upper_bound( b + 1, b + 1 + tmp, v ) - b - 1; 82 int ans = 0; 83 if( k > 0 ) ans = query( root[r], root[l-1], k, 1, tmp ); 84 printf( "%d\n", ans ); 85 } 86 } 87 return 0; 88 }
主席树 | | 可持久化线段树,布布扣,bubuko.com
标签:style blog http color os io 数据 for
原文地址:http://www.cnblogs.com/LJ-blog/p/3924737.html