310 字
2 分钟
Educational Codeforces Round 157 D题 异或构造

https://codeforces.com/problemset/problem/1895/D

题目大意#

已知异或的差分(异或意义的差分),求原数组,要求原数组是一个排列

分析#

异或又称模二加(其实也是模二减,所以自己才能消去自己),加法有的性质它都有。本题相当于是给了差分,在不知道初始项的情况下求原数组。我们可以假设 a1 = 0 ,先得到一个数组。根据异或的性质可知这个数组与答案只相差一个整体异或的偏移量shift。

解决#

如何求这个偏移量?

由于题目保证答案一定存在,所以我们只需要尽量让数组接近答案就够了。

已知答案是一个0-n-1的排列。我们按位来考虑,对于某一个二进制位, (ansi==0)>=(ansi==1)\sum (ans_i==0) >= (\sum ans_i==1) 恒成立

也就是说如果我们发现构造出的数组中某一位二进制上1比0多就翻转一下。

复杂度O(nlogn)O(nlogn)

代码#

void solve()
{
int n;
cin >> n;
for (int i = 1; i < n; i++)
{
cin >> a[i];
}
int tmp=0;
for(int i=0;i<n;i++)
{
tmp^=a[i];
ans[i]=tmp;
}
int shift=0;
for(int i=0;i<25;i++)
{
int cnt=0;
for(int j=0;j<n;j++)
{
cnt+=ans[j]>>i&1;
}
if(cnt>n-cnt)
{
shift+=1ll<<i;
}
}
for(int i=0;i<n;i++)
{
cout<<(ans[i]^shift)<<' ';
}
cout<<endl;
}
Educational Codeforces Round 157 D题 异或构造
https://fuwari.vercel.app/posts/cf-edu-round-157-d-xor/
作者
sinlin
发布于
2023-11-16
许可协议
CC BY-NC-SA 4.0