51nod2383
2383 高维部分和
- 1 秒
- 131,072 KB
- 80 分
- 5 级题
输入一个长度为n的数组a[i],下标从0开始(0到n-1)
保证n是2的整数次幂,
对于每个i (0 <= i < n)
求所有满足((i & j) == j)的a[j]之和。
其中&表示按位与,即C++和C中的&,Pascal中的and。
对于100%的数据,1 <= n <= 220, 0 <= a[i] <= 1000
对于70%的数据,1 <= n <= 215,
对于50%的数据,1 <= n <= 210,
虽然这是一个简单题,但是为了降低难度,你可以看看下面的解释。
对于一个一维数组求部分和,可以使用如下代码
for (int i = 1; i <= n; i++) {
a[i] += a[i - 1];
}
对于一个二维数组求部分和,可以使用如下代码
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
a[i][j] += a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1];
}
}
或如下代码
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
a[i][j] += a[i][j - 1]
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
a[i][j] += a[i - 1][j]
}
}
第二份代码看起来更麻烦更慢,来考虑一下三维的情况。
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
for (int k = 1; k <= n; k++) {
a[i][j][k] += a[i][j][k - 1] + a[i][j - 1][k] + a[i - 1][j][k];
a[i][j][k] -= a[i][j - 1][k - 1] + a[i - 1][j - 1][k] + a[i - 1][j][k - 1];
a[i][j][k] += a[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++) {
a[i][j][k] += a[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++) {
a[i][j][k] += a[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++) {
a[i][j][k] += a[i - 1][j][k];
}
}
}
第二份代码就不一定更慢了(第二份复杂度大约3n^3,第一份复杂度大概8n^3)
随着维度更高,第一份代码容斥时项数越来越多,而第二份只是多一次遍历整个数组,优势越来越大。
同样的思路能不能推广到更高维的情况呢?
收起
输入
第一行一个整数n
接下来n行n个整数,表示a[i]
输出
输出共n行,其中第i(0 <= i < n)行表示i的答案。
输入样例
8
1
2
4
8
16
32
64
128
输出样例
1
3
5
15
17
51
85
255 sol:表示只要找找规律就行了(假)
大概像是前缀和一样呗,对于每一位,加上异或那位的值就可以了,这样是不会重复的,
#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
ll s=;
bool f=;
char ch=' ';
while(!isdigit(ch))
{
f|=(ch=='-'); ch=getchar();
}
while(isdigit(ch))
{
s=(s<<)+(s<<)+(ch^); ch=getchar();
}
return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
if(x<)
{
putchar('-'); x=-x;
}
if(x<)
{
putchar(x+''); return;
}
write(x/);
putchar((x%)+'');
return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=;
int n,a[N];
int main()
{
freopen("std.in","r",stdin);
freopen("std.out","w",stdout);
int i,j;
R(n);
for(i=;i<n;i++) R(a[i]);
for(j=;j<=n;j<<=)
{
for(i=;i<n;i++) if((i&j)==j)
{
a[i]+=a[i^j];
}
}
for(i=;i<n;i++) Wl(a[i]);
return ;
}
/*
input
8
1
2
4
8
16
32
64
128
output
1
3
5
15
17
51
85
255
*/
51nod2383的更多相关文章
随机推荐
- Csharp—碎片知识积累
1.获取应用程序的工作目录 2.将两个字符串组成一个新的路径: 3.MessageBox使用(弹出一个消息框)(第一个参数是消息内容,第二个参数是消息标题,第三个参数是按钮设置,第四个参数是消息内容前 ...
- 高效、易用、功能强大的 api 管理平台
前言导读 实际环境的需求可以说是:只有你没想到,没有实现不了的,征对于目前实际开发.测试.生产等环境中,需要用到各类的接口可达几十.甚至上百个,因此,必须需要一个统一管理的工具平台来统一管理这类接口, ...
- Javascript设计模式之我见:观察者模式
大家好!本文介绍观察者模式及其在Javascript中的应用. 模式介绍 定义 定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新. 类图及说明 S ...
- eletron打包
https://www.cnblogs.com/BigJ/p/electron.html https://www.cnblogs.com/kakayang/p/9559777.html
- 北京教育软件创业公司招 .net工程师
北京教育软件创业公司,招 .net工程师,月工资2万左右,有合适的朋友帮忙推荐下,要求水平稍高一些的.产品目前用Winform开发的.创始人两个清华,一个北大.老板在美国待了七年回来的,爱人在清华教书 ...
- H5 70-清除浮动方式五
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- H5 31-CSS元素显示模式转换
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- pandas删除某一列的方法
方法一:直接del df['column-name'] 删除sub_grade_列, 输入del df['sub_grade_x'] 方法二:采用drop方法,有下面三种等价的表达式: 1. df= ...
- Of Study
Bacon Reading maketh a full man; conference a ready man; and writing an exact man. And therefore, if ...
- 【学习总结】C-翁恺老师-入门-第0周<程序设计与C>
[学习总结]C-翁恺老师-入门-总 1-首先按视频说的下载编辑器 <DevC++> 并一路默认设置: 安装包下载链接 (我有vc6.0不过预感告诉我老师要用类似CS50里那种命令行编辑器? ...