zoukankan      html  css  js  c++  java
  • 浅谈高维前缀和

    前言

    高维前缀和听起来是个很高级的东西,其实也挺简单的。

    应该说,它就是利用了状压的思想吧。

    朴素算法

    考虑朴素情况下,要求一个(k)维前缀和该怎么做?

    (k)维数组啊。

    比如当(k=1)时,我们会这么写:

    for(int i=1;i<=n;++i) s[i]+=s[i-1];
    

    又比如(k=2)时,我们会这么写:

    for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) s[i][j]+=s[i][j-1];
    for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) s[i][j]+=s[i-1][j];
    

    (当然,(k=2)时还有容斥写法,这里就不说了,因为在扩展到高维后容斥会爆炸。)

    于是,我们就发现,以(s_{i,j})为例,其实每次就相当于枚举某一维,然后将它加上这一维减(1)位置上(s)的值,即(s_{i,j-1})或者(s_{i-1,j})

    高维前缀和

    考虑一下状压,例如对于一个三维前缀和(s_{i,j,k})(0le i,j,k<p),那么我们就可以把它压成(s_{ip^2+jp+k})

    然后我们同样枚举每一维,其实就是枚举一个(p^x(0le x<3)),然后在(0sim p^3-1)范围内枚举(s_i),若(i)(x)维上值大于(0),我们就可以将它加上(s_{i-p^x})

    这个思路应该是比较简单的吧。

    代码

    for(int k=1;k<=n;k*=p) for(int i=0;i<=n;++i) (i/k)%p&&(s[i]+=s[i-k]);//模板
    
  • 相关阅读:
    mac-常用命令
    react-redux-数据流
    ##通讯录阶段重要代码
    ##DAY15——UICollectionView
    ##DAY14——StoryBoard
    通讯录——单例
    通讯录——选择图片
    ##DAY13——可视化编程之XIB
    ##DAY12 UITableViewCell自定义
    ##DAY10 UITableView基础
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/HDPreSum.html
Copyright © 2011-2022 走看看