资源描述:
《算法合集之《二分法统计问题》》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、二分法统计问题江苏省淮阴中学李睿简介一定范围内计数问题特点:1描述简单2要求对数据动态维护,动态计算解决手段:特殊的统计模式和结构线段树动态处理可以映射在一个坐标轴上的一些固定线段,例如求并区间的总长度,或者并区间的个数等等。优点:随时插入一个区间或删除一个已有区间,并同时用低耗费维护需要的性质。线段树-构造思想下图显示了一个能够表示[1,10]的线段树:线段树-动态数据结构TypeTnode=^Treenode;Treenode=recordB,E:integer;Count:integer;LeftChild,Rightchild:Tnode;End;其
2、中B和E表示了该区间为[B,E];Count为一个计数器,通常记录覆盖到此区间的线段的个数。LeftChild和RightChild分别是左右子树的根。线段树-静态数据结构用数组B[],E[],C[],LSON[],RSON[]。设一棵线段树的根为v。那么B[v],E[v]就是它所表示区间的界。C[v]用来作计数器。LSON[v],RSON[v]分别表示了它的左儿子和右儿子的根编号。线段树-建树从根对应的区间[a,b]出发,每次分成两个部分,分别建立对应的左右子树,直到面临一个初等区间[x,x+1]。线段树-插入删除线段将区间[c,d]插入线段树T(a,b)
3、,并设T(a,b)的根编号为vprocedureINSERT(c,d;v)Beginmid=(B[v]+E[v])div2;ifc≤B[v]andE[v]≤dthenC[v]←C[v]+1elseifcmidthenINSERT(c,d;RSON[v]);end线段树-一个特殊性质举例要得到线段树上线段并集的长度,增加一个数据域M[v],讨论:C[v]>0,M[v]=E[v]-B[v];C[v]=0且v是叶子结点,M[v]=0;C[v]=0且v是内部结点,M[v]=M[LSON[v]]+M[RS
4、ON[v]];线段树-变形,对点统计[例一]一位顾客要进行n(1≤n≤5000)天的购物,每天他会有一些帐单。每天购物以后,他从以前的所有帐单中挑出两张帐单,分别是面额最大的和面额最小的一张,并把这两张帐单从记录中去掉。剩下的帐单留在以后继续统计。输入的数据保证,所有n天的帐单总数不超过1000000,并且每份帐单的面额值是1到1000000之间的整数。保证每天总可以找到两张帐单。建立点线段树,范围是[1,1000000],即每种面额的帐单设为一个叶结点。如果C[LSON[v]]>0,那么树v中的最小值一定在它的左子树上。如果C[RSON[v]]>0,它的最
5、大值在右子树上;一种静态统计方法[例二]IOI2001MOBILES:在一个N*N的方格中,开始每个格子里的数都是0。现在动态地提出一些问题和修改:提问的形式是求某一个特定的子矩阵(x1,y1)-(x2,y2)中所有元素的和;修改的规则是指定某一个格子(x,y),在(x,y)中的格子元素上加上或者减去一个特定的值A。现在要求你能对每个提问作出正确的回答。1≤N≤1024,提问和修改的总数可能达到60000条。一维序列求和设序列的元素存储在a[]中,a的下标是1..n的正整数,需要动态地更新某个a[x]的值,同时要求出a[x1]到a[y1]这一段所有元素的和。
6、对于序列a[1..n],我们设一个数组C[1..n],C[i]=a[i-2k+1]+…+a[i],其中k为i在二进制下末尾0的个数1001010110010000k=4计算C[x]对应的2kLOWBIT(x)2k=xand(xxor(x-1))修改一个a[x]的值与哪些C相关?例如x=76=(1001010)2,从形式上进行观察,可以得到:p1=1001010p2=1001100p3=1010000p4=1100000p5=10000000修改C[p1],C[p2],…procedureUPDATA(x,A)beginp←xwhile(p<=n)dobegi
7、nC[p]←C[p]+Ap←p+LOWBIT(p)endend维护的费用:logn求a[1]-a[x]的和functionSUM(x)beginans←0p←xwhile(p>0)dobeginans←ans+C[p]p←p-LOWBIT(p)endreturnansendC[p]=a[p-2k+1]+^+a[p]下一个p=x-2k推广为原来的二维问题,把C构造成C[x,y],其每一维定义与原来相同。推广后算法:两层嵌套,一次维护费用为O(log2n)集合{3,4,5,8,19,6}静态二叉排序树实现构造过程1递归:建立所有点坐标的映射Xp←0作为X映射中的
8、指针procedureBUILD(ID:intege