CSU 1977: Bit-reversal Permutation
来源:互联网 发布:印第安保留地知乎 编辑:程序博客网 时间:2024/06/11 01:49
CSU 1977: Bit-reversal Permutation
Description
A fast Fourier transform (FFT) algorithm computes the discrete Fourier transform (DFT) of a sequence, or its inverse (IFFT). Fourier analysis converts a signal from its original domain (often time or space) to a representation in the frequency domain and vice versa. An FFT rapidly computes such transformations by factorizing the DFT matrix into a product of sparse (mostly zero) factors. As a result, it manages to reduce the complexity of computing the DFT from O(n2), which arises if one simply applies the definition of DFT, to O(nlogn), where n is the data size.
——From Wikipedia
During this summer holiday, csuxushu feels so bored to learn FFT. Because FFT is a complicated algorithm, he need to apply a bit-reversal permutation to a sequence first before DFT which is a part of FFT.
In applied mathematics, a bit-reversal permutation is a permutation of a sequence of n items, where n = 2^k is a power of two. It is defined by indexing the elements of the sequence by the numbers from 0 to n ? 1 and then reversing the binary representations of each of these numbers (padded so that each of these binary numbers has length exactly k). Each item is then mapped to the new position given by this reversed value.
Because all fellows in CSU(California State University ) can apply FFT, NTT or even FWT, it is a shame that he even doesn’t know how to take the first step. As one of the best computer programmer in CSU, can you help him?
You may think this problem is too hard to solve. In fact, it is a piece of cake to you. Remember to see the hint :-)
Input
The first line of the input gives the number of test cases T(T≤10); T test cases follow.Each test case contains a number sequence.
In each case, the first line is a number N(1≤N≤10^5), the number of elements in the following sequence.The second line is the sequence.Its length may not be exactly a power of two, so you can append some zeros to make it the minimal power of two larger than or equal to N.
Output
For each test case, output the sequence from input in bit-reversal order.
Sample Input
1621 58 96 12 45 65
Sample Output
21 45 96 0 58 65 12 0
Hint
中文提示:可以看到,我们最终处理的系数从左至右的编号的二进制形式分别为000,100,010,110,001,101,011,111,若将其二进制反序,可得000,001,010,011,100,101,110,111,这些反序的二进制编码是从小到大排列的。也就是说,我们可以按照每个下标的二进制编码来确定处理系数的顺序。这种方法就称为位逆序置换(Bit-reversal permutation)。
Source
2017年8月月赛
Author
徐戍
题目大意
模拟实现DFT的第一步:将数组元素重新按位逆序排列。
输入:a0,a1,a2,a3,a4,a5,a6,a7 二进制下标 000,001,010,011,100,101,110,111
输出:a0,a4,a2,a6,a1,a5,a3,a7 二进制下标 000,100,010,110,001,101,011,111
思路
如果我们能够将输出的二进制下标按顺序生成出来,那么只要依次输出下标对应的元素即可,因此我们要找出位逆序排列的规律。
其实位顺序排列和位逆序排列是同样的一串字符从不同的方向来看罢了,完全可以按顺序生成二进制后反向转换成十进制即可。
#include <iostream>#include <cstdio>#include <string>#include <cstring>using namespace std;int t,n;int a[100005];int b[100005];int btc[100005];int len;int reserval(int x){ int ans = 0; for(int i = len-1 ; i >= 0 ; i--) { if((x & (1 << len-1-i)) == 0) continue; ans = ans | (1 << i); } return ans;}int main(){ int num = 1; for(int i = 2 ; i <= 100000 ; i *= 2) b[i] = num++; num = 1; for(int i = 1 ; i <= 100000 ; i++) if(!b[i]) btc[i] = num; else btc[i] = num++; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i = 0 ; i < n ; i++) scanf("%d",&a[i]); len = btc[n]; int nn = 1 << btc[n]; for(int i = 0 ; i < nn ; i++) printf("%d%c",reserval(i) >= n ? 0:a[reserval(i)]," \n"[i == nn-1]); } return 0;}
位运算交换 (FFT模板节选)
// 原地快速bit reversalfor(i = 0, j = 0; i < n; i++) { if(j > i) swap(a[i], a[j]); int k = n; while(j & (k >>= 1)) j &= ~k; j |= k;}
- CSU 1977: Bit-reversal Permutation
- 1977:Bit-reversal Permutation
- 1977: Bit-reversal Permutation(递归)
- Bit-reversal permutation
- Bit Reversal and Permutation
- COJ1977-Bit-reversal Permutation
- CSU1977: Bit-reversal Permutation
- CSU1977-Bit-reversal Permutation-模拟
- EPI 5.3 BIT REVERSAL
- CSU 1536 bit string reordering
- Permutation Descent Counts CSU 1968 (动态规划)
- Word Reversal
- ZOJ_1151_Word Reversal
- Word Reversal
- Word Reversal
- Word Reversal
- Word Reversal
- Word Reversal
- 每日英语阅读(三十二)
- socket(php)(短连接)(无循环,能接发一次,自动关闭)整理版本1
- NOI2002 洛谷P1196 VijosP1443 银河英雄传说
- struts框架404错误总结
- http帮助类
- CSU 1977: Bit-reversal Permutation
- c++中的引用和指针小测试
- 每日英语阅读(三十三)
- 2017.08.10【NOIP提高组】模拟赛B组
- Linux与Windows共享文件夹之samba的安装与使用(Ubuntu为例)
- 51nod 1090 3个数和为0 二分暴力。
- LWIP的IGMP
- lintcode--寻找旋转排序数组中的最小值
- C++ Primer Notes(7)