博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[ Nowcoder Contest 167 #C ] 部分和
阅读量:6814 次
发布时间:2019-06-26

本文共 1177 字,大约阅读时间需要 3 分钟。

\(\\\)


给出一个长度为\(N\)的数组\(A[i]\),保证\(N\)\(2\) 的整次幂。

对于每个 \(i\ (i\in [0,N))\)求所有满足\((i\ \&\ j) == j\)\(A[j]\)之和。

  • \(N\in [1,2^{20}]\)\(A[i]\in [1,10^3]\)

\(\\\)

\(Solution\)


考虑每一个\(i\)的答案。

\(i\) 按照二进制位分解,那么它的答案就是所有子集的答案。

换句话说,设一共有\(K\)个二进制位,建立数组 \(f[2][2][2][2]....[2]\)分别表示每一位的情况,那么有

\[ f[c_1][c_2]...[c_k]=\sum_{d_1=0}^{c_1}\sum_{d_2=0}^{c_2}...\sum_{d_k=0}^{c_k}A[d_1][d_2]...[d_k] \]

此时\(A\)数组的下标是将原来的十进制数按二进制位分解得到的数。

我们发现这是一个\(K\)维前缀和,因为它是一个子集求和。

然后题解就安利了一个“快速莫比乌斯变换”,其实是另一种高维求前缀和的方法。

一般求二维前缀和我们都是容斥做法,其实还可以每一行先求和,每一列再求和。

这个一样,从低到高按位求和即可,注意只会加上当前一位不同的答案,因为前面固定,后面更小的子集已经在当前要加的对象上累加过一次了。

因为只有两个数所以直接压成一维即可。

\(\\\)

\(Code\)


#include
#include
#include
#include
#include
#include
#include
#define N 1<<21#define R register#define gc getcharusing namespace std;typedef long long ll; ll n,lim,a[N]; inline ll rd(){ ll x=0; bool f=0; char c=gc(); while(!isdigit(c)){if(c=='-')f=1;c=gc();} while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();} return f?-x:x;} int main(){ n=rd(); lim=min(20ll,(ll)log2(n)+1); for(R int i=0;i

转载于:https://www.cnblogs.com/SGCollin/p/9752528.html

你可能感兴趣的文章
LVS启(禁)用成员
查看>>
innobackupex 备份报错
查看>>
2016 IT 运维工作计划及学习
查看>>
将一个数的二进制位模式从左到右翻转并输出
查看>>
jQuery学习之jQuery Ajax用法详解
查看>>
关于JEPLUS软件介绍——JEPLUS软件快速开发平台
查看>>
动态增加UIView到当前视图中
查看>>
怎么能看透信封
查看>>
css正方形照片墙
查看>>
找工作的程序员必懂的Linux
查看>>
shell脚本实现杨辉三角形
查看>>
ComponentOne 2019V1火热来袭!全面支持 Visual Studio 2019
查看>>
装了一款系统优化工具,如何从Mac上卸载MacBooster 7?
查看>>
使用符号表调试release程序
查看>>
Delphi 设置系统默认打印机
查看>>
AliOS Things网络适配框架 - SAL
查看>>
数组 将一个数组的元素和另一个素组的元素相加,然后赋给第三个数组
查看>>
Python常用模块汇总
查看>>
sa提开放系统下的虚拟新贵Virtualbox权技巧之xp_regwrite替换sethc.exe
查看>>
SpringBoot开发案例之整合Dubbo提供者(一)
查看>>