题意: a1 到 an 这n个数,每次操作使 ai=a1 ^ a2 ^…^ ai ,把这个操作重复 m 次,求最后所得的序列。
显然异或两次就等于没异或。考虑每个数在每一次操作后对每个数异或的次数,可以得到下面的矩阵。
其中第
i
行就是经过
多写几个数可以发现规律,这是一个杨辉三角。(比赛时没想到这点)
杨辉三角第
n
行的第
Cmn
为奇数当且仅当(
n
&
还有一个Lucas定理可以用来判断 C(n,m) % p <script type="math/tex" id="MathJax-Element-23">p</script>的值,顺便提一下。
想到这几点,后面的就很好写了。
#include <bits/stdc++.h>
using namespace std;
int a[200010];
int ans[200010];
int n,m;
int T;
int main(){
scanf("%d",&T);
while (T--){
scanf("%d %d",&n,&m);
memset(ans,0,sizeof(ans));
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
for (int i=1;i<=n;i++){
int x=i+m-2;
int y=i-1;
if ((x&y)==y){
for (int j=i;j<=n;j++){
ans[j]^=a[j-i+1];
}
}
}
for (int i=1;i<=n;i++){
if (i==1) printf("%d",ans[i]);
else printf(" %d",ans[i]);
}
putchar('\n');
}
return 0;
}