Description
There is a nonnegative integer sequence (a_{1...n}) of length (n). HazelFan wants to do a type of transformation called prefix-XOR, which means (a_{1...n}) changes into (b_{1...n}), where (b_i) equals to the XOR value of (a_1,...,a_i). He will repeat it for m times, please tell him the final sequence.
Input
The first line contains a positive integer (T(1leqslant Tleqslant 5)), denoting the number of test cases.
For each test case:
The first line contains two positive integers (n,m(1leqslant nleqslant 2×10^5,1leqslant mleqslant 10^9)).
The second line contains (n) nonnegative integers (a_{1...n}(0leqslant a_ileqslant 2^{30}−1)).
Output
For each test case:
A single line contains (n) nonnegative integers, denoting the final sequence.
Sample Input
2
1 1
1
3 3
1 2 3
Sample Output
1
1 3 1
显然,直接暴力做m次前缀异或和是不可行的,我们先用变量列几个数出来找一下规律
(记(otimes)为异或操作,(a^k)表示有(k)个(a)进行异或操作)
次数 | (a) | (b) | (c) | (d) |
---|---|---|---|---|
1 | (a) | (aotimes b) | (aotimes botimes c) | (aotimes botimes cotimes d) |
2 | (a) | (a^2otimes b) | (a^3otimes b^2otimes c) | (a^4otimes b^3otimes c^2otimes d) |
3 | (a) | (a^3otimes b) | (a^6otimes b^3otimes c) | (a^{10}otimes b^6otimes c^3otimes d) |
可以发现,对于表格中的某个位置(A[i][j])而言,其可以写成(A[i][j]=A[i-1][j]otimes A[i][j-1]),这个形式十分类似于杨辉三角,而将整个表格顺时针旋转45°后,单独查看某个变量的系数,其就是杨辉三角
稍加推理可得,对于数列中第(i)个数,其在做完(m)次操作后,对第(j)位数((i<j))的贡献是(inom{(m-1)+(j-i)}{m-1})
但直接计算的话肯定会超时。我们注意到这是异或操作,故只有奇数次的贡献才是有效的,根据组合数奇偶性定理可得,当(n & k=k)时,(inom{n}{k})才为奇数
将该定理代入之前的式子,很容易得到((m-1) & (j-i)=0),即((j-i)_2)中1的位置必定是((m-1)_2)中0的位置
我们再按照01背包的思路,每次枚举出一个((m-1)_2)的0的位置,可得到(2^k((m-1) & 2^k=0)),再将每个数的贡献累加到其之后(2^k)的位置上的数即可
/*program from Wolfycz*/
#include<map>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Fi first
#define Se second
#define ll_inf 1e18
#define MK make_pair
#define sqr(x) ((x)*(x))
#define pii pair<int,int>
#define int_inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline char gc(){
static char buf[1000000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
template<typename T>inline T frd(T x){
int f=1; char ch=gc();
for (;ch<'0'||ch>'9';ch=gc()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=gc()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
template<typename T>inline T read(T x){
int f=1; char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
inline void print(int x){
if (x<0) putchar('-'),x=-x;
if (x>9) print(x/10);
putchar(x%10+'0');
}
const int N=2e5;
int A[N+10];
int main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
int T=read(0);
while (T--){
int n=read(0),m=read(0)-1;
for (int i=1;i<=n;i++) A[i]=read(0);
for (int j=30;~j;j--){
if (m&(1<<j)) continue;
for (int i=n;i>1<<j;i--)
A[i]^=A[i-(1<<j)];
}
for (int i=1;i<=n;i++){
printf("%d",A[i]);
putchar(i==n?'
':' ');
}
}
return 0;
}