zoukankan      html  css  js  c++  java
  • 牛客网 NOIP赛前集训营-普及组(第四场)C--部分和 (高维前缀和)

    传送门

    解题思路

      高维前缀和模板题。首先,求前缀和有两种方式,比如说对于求二维前缀和来说。

    第一种 :

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

      这一种其实就相当于用了容斥原理。

    第二种 :

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

      这一种其实相当于先求出列的前缀和,再求行的前缀和。

    二维的时候这两种似乎看起来差不多,如果扩展到三维?

    第一种 :

    for(int i=1;i<=n;i++)
     	 for(int j=1;j<=n;j++)
     	   for(int k=1;k<=n;k++){
    			sum[i][j][k]=sum[i-1][j][k]+sum[i][j-1][k]+sum[i][j][k-1];
            	 sum[i][j][k]-=sum[i-1][j-1][k]+sum[i-1][j][k-1]+sum[i][j-1][k-1];
               	sum[i][j][k]+=sum[i-1][j-1][k-1];
          }
    

      这样就有点麻烦了,再来看看第二种。

    第二种 :

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

      这样就比较舒服了。

    随着维度的不断增加,第一种方法需要容斥,这个复杂度就达到了 (2^t)(t)表示维度。那么总的时间复杂度就是(O(2^t*n^t)),第二种的复杂度则是(O(t*n^t)),优秀很多。利用这个玩意,就可以算出高维前缀和,高维前缀和一般都是(n=2)的情况,一般来说就是求一个集合的超集或子集这类的东西。

    对于这道题来说其实就是一个求子集的和。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    
    using namespace std;
    const int MAXN = (1<<20)+5;
    
    inline int rd(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)) {f=ch=='-'?0:1;ch=getchar();}
        while(isdigit(ch))  {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        return f?x:-x;
    }
    
    int n,a[MAXN];
    
    int main(){
        n=rd();for(int i=0;i<n;i++) a[i]=rd();int len=log2(n);
        for(int i=1;i<=len;i++)
            for(int j=0;j<n;j++)
                if((j&(1<<(i-1)))) a[j]+=a[j^(1<<(i-1))];
        for(int i=0;i<n;i++) printf("%d
    ",a[i]);
        return 0;
    }
    
  • 相关阅读:
    【Linux】iptables相关实践,原理及参数解释
    【Linux】解决Linux服务器内存不足问题
    【原】Linux环境下Shell调用MySQL并实现定时任务
    Nginx配置,413 Request Entity Too Large错误解决
    【MAC】Mac下部分常用的小工具
    好久不见
    HashMap工作原理(转载)
    Java中long和Long有什么区别 (转载)
    Explain in detail the steps/processes that occur from the moment you type a URL in a browser and hit enter
    Find Minimum in Rotated Sorted Array leetcode java
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/10003486.html
Copyright © 2011-2022 走看看