Ta sẽ dùng tính chất:
Ai⊕j=Aj⊕i ⇒ Ai⊕i=Aj⊕j
để giải bài này.
Lưu số lần xuất hiện XOR rồi tính số cặp có thể tạo ra với XOR đó
Độ phức tạp: O(n.log(n))
𝓒𝓸𝓭𝓮 𝓒++
#∈clude<iostream>#∈clude<→→r>#∈clude<map>longlong→ng(longlonga){returna⋅a-12;}∫ma∈(){std::iosbase::syncwithstdio(false);std::c∈.tie(νllptr);std::cout.tie(νllptr);∫n;unsig≠d∫x;longlongdem=0;std::c∈〉n;std::map<unsig≠d∫,longlong>f;for(∫i=1;i≤n;++i){std::c∈〉x;f[xi]++;}for(std::map<unsig≠d∫,longlong>::itera→rit=f.beg∈();it≠f.end();++it)dem+=→ng(it→second);std::cout〈dem;return0;}
~(Ko thích dùng using namespace std;)~
Ta biến đổi công thức:
A[i] ^ j = A[j] ^ i
-> A[i] ^ j ^ (i ^ j) = A[j] ^ i ^ (i ^ j)
-> A[i] ^ i ^ (j ^ j) = A[j] ^ j ^ (i ^ i)
-> A[i] ^ i ^ 0 = A[j] ^ j ^ 0
-> A[i] ^ i = A[j] ^ j
__=> Vậy với 1 giá trị là hợp lệ ta cần đếm số cặp phân biệt với (i != j) và cặp (i, j) cũng đc coi là (j, i)__
Code Mẫu:
#include <bits/stdc++.h>
using namespace std;
constexpr int mx = 1e5;
int A[mx + 5];
signed main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
int n;
cin >> n;
for (int i = 1; i <= n; ++i){
cin >> A[i];
A[i] ^= i;
}
sort(A + 1, A + n + 1);
A[n + 1] = -1;
int cnt = 1;
int ans = 0;
for (int i = 1; i <= n; ++i)
if (A[i] == A[i + 1]) ++cnt;
else{
ans += (cnt - 1)*cnt/2;
cnt = 1;
}
cout << ans;
}