完全に忘れていたので復習
リンク
atcoder.jp
問題概要
長さNの数列A,Bが与えられる。それぞれの数列から要素を取り出してくる方法は通り存在するが、その通りの要素同士の和について全てXORを取った値を求めよ
制約
考察
当然愚直は間に合わないので桁毎に注目したい気分になります。
上の桁から見て行くのが頭の良いポイントです。
2進数で考えた時、K桁目に1がくる場合を考えます。
数列の全要素に対してmodを取ります。この操作が上の桁から見ることによって可能になります。
この時2要素の和の取りうる値Sは、となり、K桁目に1が来るのはまたはの場合となります。数列Aの値に対してこの範囲に和が来るような数列Bの要素の個数は二分探索や尺取り法などによって求める事ができます。
実装
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long int ll;
int main(){
cin.tie(nullptr);
ios::sync_with_stdio(false);
int n; cin >> n;
vector<int> a(n),b(n);
for(int i=0;i<n;i++){
cin >> a[i];
}
for(int i=0;i<n;i++){
cin >> b[i];
}
int ans=0;
for(int v=(1<<28);v;v>>=1){
for(int i=0;i<n;i++){
a[i]&=(v*2-1);
b[i]&=(v*2-1);
}
sort(a.begin(),a.end());
sort(b.begin(),b.end());
int t=0;
for(int i=n-1,j=0,k=0,l=0;i>=0;i--){
while(j<n&&a[i]+b[j]<v)j++;
while(k<n&&a[i]+b[k]<2*v)k++;
while(l<n&&a[i]+b[l]<3*v)l++;
t+=(k-j)+(n-l);
t&=1;
}
if(t)ans|=v;
}
cout << ans << endl;
return 0;
}
類題
Problem - B - Codeforces
View problem - XOR Sum (info1cup17_xorsum) :: oj.uz