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. 移动端h5页面编写样式重置

    @charset "UTF-8"; /* stylelint-enable */ /* 重置样式 */ * { -webkit-tap-highlight-color: trans ...

  2. CentOS下安装Apache

    CentOS下安装Apache,首先在用户状态下使用su root命令切换到超级管理员界面,让后开启终端,进行apache的安装过程. [root@localhost centos]# yum ins ...

  3. Spring MVC数据绑定入门总结

    1.基本类型 基本类型参数不可为空 正例:http://localhost:8080/demo/he?id=2 反例:http://localhost:8080/demo/he?id=(报400错误) ...

  4. 开源纯C#工控网关+组态软件(二)工控网关的实现

    一.   工控网关是什么 网关是物联网和工控系统的核心组件.网关起的是承上启下的作用.上即上位机,电脑/触屏监控系统.MES这些:下即下位机,包括PLC.传感器.嵌入式芯片等. 不同厂家的下位机,往往 ...

  5. Linux命令(一)

    需要用Xshell连接Linux时: 先在终端输入命令:service  sshd  start(开启ssh服务) 1.netstat -tnl:查看端口状态的命令(如 查看22端口) 2.servi ...

  6. Dockerfile cnetos7_nginx1.15.10

    FROM centos:7 MAINTAINER yuyongxr yuyongxr@gmail.com LABEL Discription="centos7+nginx1.15.10&qu ...

  7. C++类的描述

    类的描述分为两个部分,public和private public可以用来定义函数,对类的对象进行操作,对于用户是可见的,是用户对对象操作的唯一手段. private部分用于定义函数和数据成员,这些函数 ...

  8. 现代程序设计 homework-10

    经过大半学期的学习和练习, 我们把学到的东西综合起来. 通过<现代程序设计>这门课,自己的确学到了好多东西.其实并不是说讲课有多棒,一是因为讲课的次数其实并不多,二是讲课的内容其实感觉并没 ...

  9. use redis instance in docker hub

    redis - Docker Hubhttps://hub.docker.com/_/redis

  10. Nginx会话保持之nginx-sticky-module模块

    Nginx会话保持之nginx-sticky-module模块 - 天行健,君子以自强不息:地势坤,君子以厚德载物. - CSDN博客https://blog.csdn.net/huangjinjin ...