训练赛002 F题 -XorXor

题意

给出两个公式:
f(i,j)=ai^ (ai+1)^ (ai+2)^ …^aj 。(此为异或和,虽然为和但是是许多数的异或结果)
s=[f(1,1) ^ f(1,2) … f(1,n) ] ^ [f(2,2) ^ f(2,3) … f(2,n)] ^ [f(n,n)]
求出s的最终结果.

题解

首先要知道一件事情,异或的逆运算是异或
所以假设k1=[f(1,1) ^ f(1,2) … f(1,n) ],其中a[1]是被异或了(n-1+1)次
那么k2=[f(2,2) ^ f(2,3) … f(2,n)] ,只需要把k1异或的(n-1+1)次a[1]异或掉就是k2。
同理k3=k2异或(n-2+1)次a[2],k4=k3异或(n-3+1)次a[3] …
最终答案就是k1到kn的异或和。
所以只需要从头到尾扫一遍即可出结果。
这里还要知道一件事可以使上述过程简化,任何数异或它本身=0,任何数异或0是它本身,所以一个数自身异或奇数次是它本身,自身异或偶数次是0。
————————————————
版权声明:本文为CSDN博主「晚樱。」的原创文章,遵循 CC 4.0 BY 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_45530271/article/details/103809647

此为出题人的题解,我本来想用递归求,不过会超时。
偶数个相同的数异或时为0,而奇数个则为其本身。
下面代码中的第一个循环是为了求出k1。第二个循环中的ans表示的是每次异或ki得到的结果,其中的now表示的是ki。k1循环一次更新一次,ans也是。

代码

#include
#include
using namespace std;
const int N=100007;
int a[N],ans,now,n,t;

int main(){
cin>>t;
while(t–){
cin>>n;
now=ans=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if((n-i+1)%2)now^=a[i];
}
for(int i=1;i<=n;i++){
ans^=now;
if((n-i+1)%2)now^=a[i];
}
cout<<ans<<endl;
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值