nverse
Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 110 Accepted Submission(s): 44
Problem Description
Mike has got a huge array b,
and he is told that the array is encrypted.
The array is encrypted as follows.
Let ai(0≤i<n) be
the i-th
number of this original array.
Let bi(0≤i<n) be
the i-th
number of this encrypted array.
Let n be
a power of 2,
which means n=2k.
The bi is
calculated as following.
bi=∑0≤j<nf((i or j) xor i)aj
f(x) means,
if the number of 1 in
the binary of x is
even, it will return 1,
otherwise 0.
Mike want to inverse the procedure of encryption.
Please help him recover the array a with
the array b.
Input
The first line contains an integer T(T≤5),
denoting the number of the test cases.
For each test case, the first line contains an integer k(0≤k≤20),
The next line contains n=2k integers,
which are bi respectively.
It is guaranteed that, ai is
an integer and 0≤ai≤109.
Output
For each test case, output ‘‘Case #t:‘‘ to represent this is the t-th case. And then output the array a.
Sample Input
2 0 233 2 5 3 4 10
Sample Output
Case #1: 233 Case #2: 1 2 3 4
分治。吧矩阵构造出来们发现有规律 ,然后就可以用分治求解了。
#include<iostream> #include<algorithm> #include<stdio.h> #include<string.h> #include<queue> using namespace std; const int mmax = (1<<21); const int inf = 0x3fffffff; typedef __int64 LL; LL b[mmax],a[mmax]; void cdq(int l,int r) { if(l==r) { a[l]=b[l]; return ; } int mid=(l+r)>>1; for(int i=l;i<=mid;i++) { LL tmp=b[i]+b[i+(r-l+1)/2]; b[i]=(tmp-(b[r]-b[mid]))/2; b[i+(r-l+1)/2]-=b[i]; } cdq(l,mid); cdq(mid+1,r); } int get(int x) { int cnt=0; while(x) { if(x&1) cnt++; x/=2; } return cnt; } int c[mmax]; void test(int k) { for(int i=0;i<(1<<k);i++) { int sum=0; for(int j=0;j<(1<<k);j++) if( get((i|j)^i ) %2==0 ) sum+=a[j+1]; b[i+1]=sum; } } int main() { int t,k,ca=0; cin>>t; while(t--) { scanf("%d",&k); for(int i=1;i<=(1<<k);i++) scanf("%I64d",&b[i]); // for(int i=1;i<=(1<<k);i++) // scanf("%d",&a[i]); // test(k); cdq(1,(1<<k)); printf("Case #%d: ",++ca); for(int i=1;i<=(1<<k);i++) printf("%I64d%c",a[i],i==(1<<k)?'\n':' '); //test(k); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。