CSU1977: Bit-reversal Permutation

CSU1977: 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

1
6
21 58 96 12 45 65

Sample Output

21 45 96 0 58 65 12 0

Hint
Bit-reverse order

Bit-reverse Order
中文提示:可以看到,我們最終處理的係數從左至右的編號的二進制形式分別爲000,100,010,110,001,101,011,111,若將其二進制反序,可得000,001,010,011,100,101,110,111,這些反序的二進制編碼是從小到大排列的。也就是說,我們可以按照每個下標的二進制編碼來確定處理係數的順序。這種方法就稱爲位逆序置換(Bit-reversal permutation)。

Source

2017年8月月賽

Author

徐戍

比賽中將問題想複雜了,好久也沒搞出來。實際上直接按照先0後1的次序,遞歸地生成順序序列的二進制數碼,同時逆序地計算出這些數碼對應的十進制數,直接取出數組中元素就行了。比如我們生成的是 000,001,010,011,100,101,110,111 這八個數,本來是對應十進制 0,1,2,3,4,5,6,7 的,但我們對每一個二進制數逆序地轉換進制,例如對 011 ,按照 0×20+1×21+1×22=6 來計算。這樣得出的自然就是位逆序置換後所對應的下標了。取這個下標對應的元素輸出即得答案。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 1e5+10;

int sample[maxn*10];
int T, n, k;

void dfs(int kk, int index){
    if(kk == 0){                    // 已產生k位二進制數,並已經知道了它們逆序後對應的十進制數。
        if(index == (1<<k)-1)       // 不論如何做位逆序置換,最後一個輸出的一定是二進制全爲1的數。輸出它後換行。
            printf("%d\n", sample[index]);
        else                        // 否則輸出後空格。
            printf("%d ", sample[index]);
        return;
    }
    dfs(kk-1, index+0);             // 遞歸調用的同時進行逆序進制轉換。
    dfs(kk-1, index+(1<<(k-kk)));
}

int main(){
#ifdef TEST
freopen("test.txt", "r", stdin);
#endif // TEST

    cin >> T;
    while(T--){
        memset(sample, 0, sizeof(sample));
        scanf("%d", &n);
        for(int i = 0; i < n; i++){
            scanf("%d", &sample[i]);
        }
        k = 0;
        while(1<<k < n) k++;        // 求出令2^k不小於n的最小k值。
        dfs(k, 0);
    }

    return 0;
}

/**********************************************************************
    Problem: 1977
    User: xyJiang
    Language: C++
    Result: AC
    Time:400 ms
    Memory:5924 kb
**********************************************************************/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章