[ARC092B] Two Sequences

[ARC092B] Two Sequences

细节超多,开始找不到任何数据结构维护。

考虑比较暴力的做法。

对答案每一位分别考虑,设当前考虑到第 i i i 位。

计算所有数模 2 i + 1 2^{i + 1} 2i+1 的余数,并升序排序使其满足单调性。(以下都按余数讨论)

若对于一个数 a a a,有数 b b b 满足 ( a + b )   m o d   2 i + 1 ≥ 2 i (a+b)\bmod 2^{i+1}\geq 2^i (a+b)mod2i+12i,则 a , b a,b a,b 原数之和第 i i i 位为 1 1 1

那么对于每个 a i a_i ai 分类讨论:

  • a i ≤ 2 i − 1 a_i \le 2^{i-1} ai2i1,则答案在 [ 2 i − a , 2 i + 1 − a − 1 ] [2^i-a,2^{i+1}-a-1] [2ia,2i+1a1] 范围内,二分统计个数即可。
  • 否则即 a i > 2 i − 1 a_i>2^{i-1} ai>2i1,则答案在 [ 0 , 2 i + 1 − a − 1 ] ∪ [ 2 i + 1 + 2 i − a , 2 i + 1 − 1 ] [0,2^{i+1}-a-1] \cup [2^{i+1}+2^i-a,2^{i+1}-1] [0,2i+1a1][2i+1+2ia,2i+11] 范围内,二分统计个数即可(两区间不交)。

对于每一位的总个数判断奇偶性添加贡献即可。

时间复杂度 O ( n log ⁡ n log ⁡ V ) \mathcal O(n\log n\log V) O(nlognlogV)

#include<bits/stdc++.h>

using namespace std;

#define int long long
typedef long long ll;

#define ha putchar(' ')
#define he putchar('\n')

inline int read()
{
	int x = 0, f = 1;
	char c = getchar();
	while (c < '0' || c > '9')
	{
		if (c == '-')
			f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9')
		x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
	return x * f;
}

inline void write(int x)
{
	if(x < 0)
	{
		putchar('-');
		x = -x;
	}
	if(x > 9)
		write(x / 10);
	putchar(x % 10 + 48);
}

const int _ = 2e5 + 10;

int n, a[_], b[_], c[_], d[_], ans;

signed main()
{
	//	a[1] = 1, a[2] = 2;
	//	cout << upper_bound(a + 1, a + 2 + 1, 3) - a;
	n = read();
	for(int i = 1; i <= n; ++i) a[i] = read();
	for(int i = 1; i <= n; ++i) b[i] = read();
	for(int x = 30; x >= 0; --x)
	{
		int nw = 1 << x, t = 0;
		for(int i = 1; i <= n; ++i) c[i] = a[i] % (nw << 1);
		for(int i = 1; i <= n; ++i) d[i] = b[i] % (nw << 1);
		sort(c + 1, c + n + 1), sort(d + 1, d + n + 1);
		for(int i = 1; i <= n; ++i)
		{
			if(c[i] <= nw)
			{
				// [2^i-a,2^{i+1}-a-1]
				int ps1 = upper_bound(d + 1, d + n + 1, (nw << 1) - c[i] - 1) - d - 1;
				int ps2 = lower_bound(d + 1, d + n + 1, nw - c[i]) - d - 1;
				t += ps1 - ps2;
			}
			else
			{
				// [2^{i+1}+2^i-a,2^{i+1}-1]
				// [0,2^{i+1}-a-1]
				int ps1 = upper_bound(d + 1, d + n + 1, (nw << 1) - 1) - d - 1;
				int ps2 = lower_bound(d + 1, d + n + 1, (nw << 1) + nw - c[i]) - d - 1;
				t += ps1 - ps2;
				ps1 = upper_bound(d + 1, d + n + 1, (nw << 1) - c[i] - 1) - d - 1;
				ps2 = lower_bound(d + 1, d + n + 1, 0) - d - 1;
				t += ps1 - ps2;
			}
		}
		//		cout << nw << ": " << t <<"\n";
		if(t & 1) ans |= nw;
	}
	write(ans), he;
	return 0;
}

/*

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值