NOIP模拟 B君的数组 题解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NOIP模拟 B君的数组 题解相关的知识,希望对你有一定的参考价值。

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。

%%%%%%%%%%%%%毕克dalao  Orzzzzzzzzzzzz

题目大意:

给出一个数组a,大小是2^k,下标从0开始。

求:对于每个x(0<=x<2^k),下标满足x&i = i的所有ai的和。

输入格式:

第一行有一个整数N,表示数组的大小。

接下来N行,每行一个整数,表示ai。

输出格式:

每行输出一个整数,表示所求答案。

输出共包含N行。

样例输入:

4

1

2

4

8

样例输出:

1

3

5

15

 

数据规模:

对于100%的数据,满足1<=k<=20,1<=ai<=2000.

对于10%的数据,满足1<=k<=10.

 

分析:

直接枚举x,与每一个i做and运算是不现实的,必定会超时。

因此我们要换一个思路:

枚举ij,其中(1<<i) < n,0 <= j < n.

这样,对于每一个j,我们只需要判断j>>i后个位是否为1。

如果个位为1,说明此时j的二进制第i+1位为1,则j & (j^(1<<i)) = j^(1<<i),a[j] += j^(1<<i).

不妨手动模拟一下小数据的计算过程,帮助理解。

 

AC代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstring>
 5 
 6 const int MAXN = (1<<20)+5;
 7 
 8 int n,num[MAXN];
 9 
10 int main()
11 {
12     scanf("%d",&n);
13     for(int i = 0;i < n;++ i)
14         scanf("%d",&num[i]);
15     for(int i = 0;(1<<i) < n;++ i)
16         for(int j = 0;j < n;++ j)
17             if((j>>i) & 1)
18             num[j] += num[j^(1<<i)];
19     for(int i = 0;i < n;++ i)
20         printf("%d\n",num[i]);
21     return 0;
22 }

 

以上是关于NOIP模拟 B君的数组 题解的主要内容,如果未能解决你的问题,请参考以下文章

noip模拟赛 蒜头君的树

复习---归并排序求逆序对--计蒜客2017noip模拟赛二--蒜头君的排序

[洛谷0925]NOIP模拟赛 个人公开赛 OI

2017.07.16【NOIP提高组】模拟赛B组 卫星照片 题解

NOIP模拟 (8-2情人节欢乐赛) 题解

C. 「NOIP2021模拟赛 By ZJ C」自然溢出 题解