`
hulianwang2014
  • 浏览: 685216 次
文章分类
社区版块
存档分类
最新评论
  • bcworld: 排版成这样,一点看的欲望都没有了
    jfinal

Mobius反演与树状数组

 
阅读更多

EMAIL:1025679612@qq.com

Blog: http://blog.csdn.net/wind_2008_06_29/article/details/

对于数状数组,大家应该不陌生,在此我还是说明一下它的背景吧。

我们经常会有以下要求:

对于一个序列,我们通常有两种操作,一种是取得一个子序列i到j之间的元素之和,另外一种操作是更新一个元素的值。当然,更新之后的下一次进行操作一的时候,这种改变要能够反应出来。

解法一:

大家肯定都会有一种简单的想法,用一个数组Sum,其中Sum[k]表示和1个到第k个元素的和。这样,当我们需要求第m到n个元素的和的时候,我们只需要用Sum[n]-Sum[m-1]就可以了,这个算法事实上是对的,不过,也是有问题的。当更新第k个元素的时候,我们就需要同时更新Sum数组。

问题:

以上算法事实上是对的,但是,在效率上是有问题的,这个问题反应在更新的过程,一次更新可能需要修改大量的Sum数组,这个代价是非常大的。有可能导致整个Sum数组都需要更新。

解法二:

解法二就是我们通常知道的用数状数组来解决了,同样的,我们定义状态数组TA[1…n],其中TA[k]=A[k-2^i+1]+ A[k-2^k+2]+ … + A[k],其中i是K的二进制表示中末尾的0的个数。当然为了得到2^i,我们只需要以下一行代码就可以:x&(x^(x-1)),这一行代码就可以实现,其证明过程是显然的。我们不妨定义以下函数:

int lowbit(int x){

return x&(x^(x-1));

}

我们现在的任务是要求出Sum[k],如果我们能利用TA数组方便地求出Sum[k]的值,那么,我们就很容易方便地求出 第i个到第j个元素的各。

我们有如下的结果:

int sum(int k){

int s= 0;

while(k){

s+= TA[k];

k-= lowbit(k);

}

}

这个函数显然返回的是Sum[k]的值,显然我们知道利用TA数组我们可以在log(k)的时间内求出Sum[k]的值。现在的问题是我们要快速地构造出TA数组,并且在较快的时间内能更新TA数组。也就是说,我们有如下两个问题:

问题一:构造TA数组

任意给出一个k值,我们可以不断地用k-lowbit(k)代替k,直到为0,因此,我们有一个有限地递减序列K0,K1,K2…Kt,比如,当k是5的时候,我们的这个序列就是5、4、0。

根据上面的sum函数,我们有Sum[k]=TA[K0]+TA[K1]+…+TA[Kt],当然,TA[Kt]就是TA[0]也就是0。我们可以由TA数组得到Sum数组,那么,另外一方面,我们是否可以用TA数组反解出Sum数组呢?事实上可以,当然,在这里面我们需要定义一个二元的偏序关系<=,

如果给一个元素k,我们可以不断地用k-lowbit(k)代替k,直到为0。这样我们得到一个有限递减序列K0、K1、K2…Kt=0。对于此序列中任何两个元素Ki,Kj(i>j)我们定义二元偏序<=为Kj<=Ki,也就是说,从Ki出发,不断地用Ki-lowbit(Ki)代替Ki最后能得到Kj,则有关系Kj<=Ki。

利用这个定义,我们可以把Sum[k]=TA[K0]+TA[K1]+…+TA[Kt]改写为Sum[k]为所有的TA[j]的和,其中j满足偏序j<=k。根据Mobius反演率,我们有

TA[k]为所有的Sum[i]*u(i,k)的和,其中Sum[i]为前i个元素的和,u(i,k)为Mobius反演函数,剩下的任务是求出Mobius反演函数。

根据Mobius反演定义,我们有u(k,k)=1,u(i,k)为所有-u(i,j)的和,其中j在上术定义的偏序关系中满足i<=j<=k,且j不等于k。这样显然我们就有了u(k,k)=1,u(k-lowbit(k),k)=-1,其它的I,j有u(I,j)=0,这样我们就有了TA[k]=Sum[k]- Sum[k-lowbit(k)]。这个式子表明我们可以在O(n)的复杂度内构造出TA数组(因为我们可以在O(n)复杂度为构造出Sum数组,再利用Sum我们可以在O(n)的复杂度内构造出TA)。

问题二:当一个元素变化的时候如何快速更新TA数组。

显然,如果从一个元素k开始,不断地用k-lowbit(k)代替k,我们得到一个序列K0(k)、K1、…Kt(0),则我们知道一个元素A[Ki]的变化只影响TA[Kj]其中j<=i的值。这根据TA的定义,我们知道是显然的。也就是说,当一个元素A[k]更新了的时候,我们更新TA也只需要在log(n)的时间内完成。算法如下:

void update(int inode, int iadd){

while(inode<=n){

TA[inode]+= iadd;

inode+=lowbit(inode);

}

}.

总结:

这个东西也是我在做nyoj题目

(http://acm.nyist.net/JudgeOnline/problem.php?pid=116)的时候才想到的。当时看到那个Sum是用TA来求的时候我就立刻想到了用Mobius反演可以从Sum中反解出TA数组。当然,我比较菜,高手不要喷,谢谢。

分享到:
评论

相关推荐

    莫比乌斯反演_王天懿.ppt

    莫比乌斯反演_王天懿.ppt

    通信与网络中的一种Chen-Mobius通信系统的设计和实现

    上个世纪90 年代,我国着名学者陈难先教授(现中国科学院院士、清华大学教授)将古典数论中的Mobius反演公式推广为变量连续形式的Chen-Mobius反演公式, 解决了一系列应用物理中的逆问题。 把 Mobius 变换应用于通信...

    Mobius institute——vibration analysis.pdf

    Mobius institute——vibration analysis 外国简单易用的振动分析讲稿,从中可以学会振动分析的定义以及怎么做振动分析

    manim_projects:我的项目在manim上运行

    运行该项目中的代码需...Fourier莫比乌斯反演Mobius树状数组BinaryIndexedTree快速傅里叶变换FastFourierTransform可视化元素周期表PeriodicTable三维利萨茹图形Lissajous贝塞尔曲线原理BezierBV18E411L71V更多视频..

    Android代码-mobius

    Mobius Mobius is a functional reactive framework for managing state evolution and side-effects, with add-ons for connecting to Android UIs and RxJava Observables. It emphasizes separation of concerns,...

    Mobius function

    Mobius function

    PyPI 官网下载 | mobius3-0.0.29.tar.gz

    资源来自pypi官网。 资源全名:mobius3-0.0.29.tar.gz

    Mobius, C# 和 F# 语言绑定和 Apache Spark的扩展.zip

    Mobius, C# 和 F# 语言绑定和 Apache Spark的扩展 # Mobius: 用于Spark的C# APIMobius为 Apache Spark 提供了 C# 语言绑定,支持在/F# 等. NET 框架支持的语言中实现Spark驱动程序和数据处理操作。例如 Apache Spark

    mobius,管理状态演变和副作用的功能性反应框架。.zip

    mobius是一个功能性的反应性框架,用于管理状态演化和副作用,并带有用于连接android用户界面和rxjava可观察对象的附加组件。它强调关注点的分离、可测试性和代码的有状态部分的隔离。

    Mobius

    目录 DyNamo以网络为中心的平台:Mobius 图中描绘了一个称为Mobius的以网络为中心的平台,该平台包括(a)支持集成的多云资源配置以及跨各种基础架构的高性能科学数据流,以及(b)用于与更高级别的应用程序和工作流...

    Mobius:oneM2M物联网服务器平台

    正如oneM2M所指定的,Mobius为不同服务域的IoT应用程序提供通用服务功能(例如注册,数据管理,订阅/通知,安全性)作为中间件。 不仅oneM2M设备,而且非oneM2M设备(即,通过oneM2M互通规范和KETI TAS)也可以连接...

    一种文档加密算法(chen-mobius)

    一种文档加密算法(chen-mobius),一种用chen-mobius加密文档的算法,供大家借鉴。

    mobius:一种功能性的React框架,用于管理状态演变和副作用

    Mobius是一个功能性的React式框架,用于管理状态演变和副作用,带有用于连接到Android UI和RxJava Observables的附加组件。 它强调关注点的分离,可测试性以及隔离代码的有状态部分。 要了解更多信息,请参见以获取...

    Android代码-mobius-android-sample

    TODO-MOBIUS Summary This sample is based on the TODO-MVP-RXJAVA project from the Android Architecture Blueprints repository. It converts the code from MVP using RxJava to a Mobius implementation. ...

    mobius.kt:Mobius多平台Kotlin项目框架

    莫比乌斯 Kotlin Multiplatform 实现。什么是莫比乌斯? Mobius提供的核心结构是Mobius Loop,由官方文档对其进行了最佳描述。... (来源: ) 通过将此概念与Kotlin的MPP功能相结合,mobius.kt允许您编写和测试Kot

    Mobius Mandelbrot:Hiato的Mobius Mandelbrot的Fractal Extreme插件-开源

    http://www.fractalforums.com/mandelbrot-and-julia-set/m-set-on-a-partialtotal-mobius-cylinder-looks-neat/为完整分形使用6的救助。 这实现了三种莫比乌斯类型。 如果Total大于1或小于-1,则将包装实际值。 仅...

    基于Matlab和Mobius变换的图像处理

    把Mobius变换应用到一种新型的通信系统中,以数字图像作为原始的输入信号,经过调制之后,在接收端,用跟调制载波信号不同频同相的信号进行解调。仿真结果表明,该新型的通信系统可以很好的恢复原始的数字图像信号。...

    基于Matlab和Mobius变换的图像处理毕业论文设计

    把 Mobius 变换应用到一种新型的通信系统中,以数字图像作为原始的输入信号, 经过调制之后,在接收端,用跟调制载波信号不同频同相的信号进行解调。仿真结果表明, 该新型的通信系统可以很好的恢复原始的数字图像...

    基于Matlab和Mobius变换的图像处理毕业论文.doc

    基于Matlab和Mobius变换的图像处理毕业论文.doc

Global site tag (gtag.js) - Google Analytics