2383 高维部分和

  1. 1 秒
  2. 131,072 KB
  3. 80 分
  4. 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的更多相关文章

随机推荐

  1. linux内存源码分析 - 内存回收(匿名页反向映射)

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 概述 看完了内存压缩,最近在看内存回收这块的代码,发现内容有些多,需要分几块去详细说明,首先先说说匿名页的反向映 ...

  2. UIImageView - BNR

    继续上节UINavigationController - BNR. 打开BNRDetailViewController.xib文件,向view中添加UIImageView对象,选中该对象,通过Attr ...

  3. SQLite 实现删除表中前一天的数据

    注意点1 要注意SQLite datatime()函数为何获取不到系统本地时间?这个问题,坑死我了. 解决方法详见这篇文章:SQLite datatime()函数为何获取不到系统本地时间? 注意点2: ...

  4. H5海报制作实践

    引言 年后一直处于秣马厉兵的状态,上周接到了一个紧急需求,为38妇女节做一个活动页,主要功能是生成海报,第一次做这种需求,我也是个半桶水前端,这里将碰到的问题.踩的坑,如何解决的分享给大家,讲的不到位 ...

  5. 【fetch跨域请求】cors

    当使用fetch 发起跨域请求时,CORS(跨域资源共享Cross-origin resource sharing) 请求fetch const body = {name:"Good boy ...

  6. python学习之第八篇——字典嵌套之字典中嵌套字典

    cities = { 'shanghai':{'country':'china','population':10000,'fact':'good'}, 'lendon':{'country':'eng ...

  7. atcoderI - Coins ( 概率DP)

    I - Coins Time Limit: 2 sec / Memory Limit: 1024 MB Score : 100100 points Problem Statement Let NN b ...

  8. Elasticsearch之配置详解

    Cluster 集群名称,默认为elasticsearch: cluster.name: elasticsearch 设置一个节点的并发数量,有两种情况,一种是在初始复苏过程中: cluster.ro ...

  9. Python_数据类型的补充、集合set、深浅copy

    1.数据类型的补充 1.1 元组 当元组里面只有一个元素且没有逗号时,则该数据的数据类型与括号里面的元素相同. tu1 = ('laonanhai') tu2 = ('laonanhai') prin ...

  10. MapReduce过程<原创>

    一.预处理阶段 二.Map阶段 一个Map任务被JobTracker(管家)分配到多个TaskTracker(弟弟)执行,如下图所示,弟弟的map()只负责拆分,虽然map()输出两个相同的键值对,但 ...