【Codeforces】Round #539 (Div. 2) C.Sasha and a Bit of Relax

C. Sasha and a Bit of Relax

 

题意:

给定大小为 n 的数列,问有多少对 (l, r) 满足当 mid = (l+r-1) 时,Al^Al+1……^Amid = Amid+1^Amid+2……^Ar(^表示异或)。

题解:

根据前缀和的原理,用一个数组保存异或前缀。

题目例子:

数组下标0123456
例子数据0322376
异或前缀0313071

 

那么有什么用呢?想一下,异或的原理:a^c=b, b^c=a。

数组下标0123456
例子数据0322376
异或前缀0313071

很容易看出来,如果两个相同异或前缀之间下标相差偶数,即可满足上面的条件。

然后我们只需数一下满足条件的有多少个即可。

而且,根据原理,分别计算奇偶情况的话,只需扫一遍即可,时间复杂度O(N)。

出现一次就加上 vis[num],然后vis[num]++。

为什么呢?因为分了奇偶,每次两个相同的异或前缀下标差必为偶数,也就是出现一次,就可以和前面已经出现的任意一个组为一对。


代码:

#include <iostream>
using namespace std;
int n;
int a, b;
long long ans;
int dp[2][1<<20];
int main(){
	scanf("%d", &n);
	dp[0][0] = 1;
	for(int i = 1; i <= n; ++i){
		scanf("%d", &a);
		b^=a;
		ans+=dp[i%2][b];
		++dp[i%2][b];
	}
	printf("%I64d", ans);
	return 0;
}

吐槽:

凌晨场扛不住啊,签个到B题都没调出来就跑去睡觉了,这才补掉C。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值