码迷,mamicode.com
首页 > 编程语言 > 详细

NOIP模拟 B君的数组 题解

时间:2017-09-27 20:45:23      阅读:139      评论:0      收藏:0      [点我收藏+]

标签:and   开始   说明   sub   进制   帮助   手动   16px   理解   

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

%%%%%%%%%%%%%毕克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君的数组 题解

标签:and   开始   说明   sub   进制   帮助   手动   16px   理解   

原文地址:http://www.cnblogs.com/shingen/p/7603380.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!