Just do it
题意:给出n个元素的数组a,让你异或m次得到新的数组b。 每一次得到的b[i]都是a[0]一直异或到a[i],然后把b赋值给a,循环m次得到b。
碰到异或的题,一定要考虑很重要的一个性质,a^b^b==a !!
就是说异或偶数次同一个数之后值不变!
对于这道题,我们可以考虑a的每一个数对b的影响。
对于a[1],b[i]异或a[1]的次数如下表:
第一次变换: 1 1 1 1 1
第二次变换: 1 2 3 4 5
第三次变换: 1 3 6 10 15
第四次变换: 1 4 10 20 35
可以发现,该表从左下往右上看是组合数表!于是我们可以通过求组合数轻松得到每一个数对后面的数的影响次数!
关键:如何判断影响次数的奇偶性!
这里用到了Lucas定理,简单来说就是C(x,y)是奇数当且仅当(x&y)==y。
稍微分析一下就可以得到,晚上再补分析~
先贴上代码
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn=2e5+10; 4 int a[maxn],b[maxn]; 5 int n,m; 6 int main(){ 7 int t; 8 scanf("%d",&t); 9 while(t--){ 10 scanf("%d%d",&n,&m); 11 for(int i=1;i<=n;i++){ 12 scanf("%d",&a[i]); 13 b[i]=0; 14 } 15 for(int i=1;i<=n;i++){ 16 int x=i+m-2; 17 int y=i-1; 18 if((x&y)==y){ 19 for(int j=i;j<=n;j++) b[j]^=a[j-i+1]; 20 } 21 } 22 for(int i=1;i<=n;i++) printf("%d%c",b[i],i==n?‘\n‘:‘ ‘); 23 } 24 return 0; 25 }
时间: 2024-11-10 07:54:03