比van Emde Boas线段树简单的zkw树

首先van Emde Boas树的实现比zkw树复杂了太多

其次zkw树只需要简单的位运算即可实现,效率也是相当快的

//建树
void Build(int n)  //n->输入元素个数
{  
	for(M=1; M<=n+1; M<<=1);  //树的大小为比n大的最小2次幂
	for(int i=M+1; i<=M+n; i++)  
		scanf("%d",&T[i]);  //输入n个叶子节点
	for(int i=M-1; i>0; i--)  
		PushUP(i);  //向上求父节点
}  
void PushUP(int rt)  
{  
	T[rt]=T[rt<<1]+T[rt<<1|1];  
}  
到这里完成了zkw树的建立

结构是一棵满二叉树,如下:

1.数据都存储在最底一层,从第二个节点开始存放,其余节点为0(可以Memset初始化)

2.自底向上求父节点

int Query(int s,int t)  //求区间 [s,t] 的和
{  
	int ans=0;  
	//求区间 (s,t) 的和
	for(s=s+M-1,t=t+M+1; s^t^1; s>>=1,t>>=1)  //s>>=1, t>>=1->上升到父节点
	{  /**
	   *1.只需要加当前最小区间长度(最开始长度为2)的一部分(当前最小区间长度>>2)时,直接加上
	   *2.需要整个区间时,上升到父节点,最小区间长度<<2
	   *2.反复1,2到s^t^1 == 0(s^t == 1, 即s和t只相差1,显然加完所有区间)
	   */
		cout<<"s="<void Add(int n,int v)  //n->第几个数,v->加上多少
{  
	for(T[n+=M]+=v, n>>=1; n; n>>=1)   
		PushUP(n);  
}  
通过这个函数可以修改单个数据的值,删掉数据其实就是减去其本身


最后,表示对张昆玮老师的尊敬与感谢。



你可能感兴趣的:(算法导论)