COJ1977-Bit-reversal Permutation

本文介绍了一种用于快速傅立叶变换(FFT)预处理的位逆序置换算法,该算法通过反转输入序列中元素的二进制索引来重新排序序列。文章详细解释了如何实现这一过程,并提供了一个具体的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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
中文提示:可以看到,我们最终处理的系数从左至右的编号的二进制形式分别为000,100,010,110,001,101,011,111,若将其二进制反序,可得000,001,010,011,100,101,110,111,这些反序的二进制编码是从小到大排列的。也就是说,我们可以按照每个下标的二进制编码来确定处理系数的顺序。这种方法就称为位逆序置换(Bit-reversal permutation)。
Source

2017年8月月赛
Author

徐戍

题目大意:根据hint做就好了
解题思路:找到符合二进制的长度,然后根据位运算还原出反转前的数。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<cstring>
using namespace std;
typedef long long LL;
const int MAXN=2e5+10;
int a[MAXN];

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(a,0,sizeof(a));
        int n;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        //cout<<log2(100000)<<endl;
        //cout<<pow(2,17)<<endl;
        int t=1;
        int m=0;
        while(t<n)
        {
            t*=2;
            m++;
        }
        //cout<<m<<endl;
        //cout<<(1<<m)<<endl;
        bool flag=true;
        for(int i=0;i<(1<<m);i++)
        {
            //cout<<"-----"<<i<<endl;
            int tmp=i;
            int sum=0;
            for(int j=1;j<=m;j++)
            {
                sum=sum<<1;
                //cout<<"tmp&1:"<<(tmp&1)<<endl;
                sum=sum|(tmp&1);
                tmp=tmp>>1;
                //cout<<"sum: "<<sum<<endl;
            }
            if(!flag) printf(" ");
            else flag=false;
            printf("%d",a[sum]);
            //cout<<sum<<endl;
        }
        printf("\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值