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运算是不现实的,必定会超时。
因此我们要换一个思路:
枚举i和j,其中(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君的数组 题解的主要内容,如果未能解决你的问题,请参考以下文章
复习---归并排序求逆序对--计蒜客2017noip模拟赛二--蒜头君的排序