题目大意:
给定 \(n\) 个数,找数对使其异或值为 \(k\),求满足这样数对的个数。
题目分析:
考验位运算功底的题目(实际上也不是很难),主要运用到了下列性质:
\[\begin{aligned} \because a \oplus b = k \\ \therefore a \oplus k = b \end{aligned} \]根据上述性质,题意就被转化为了:
对于任意一个数 \(a_x\),问 \(a_x \oplus k\) 在数列中的存在数量的和。
然后开个桶记录一下每个数的出现次数,求答案的时候我们先将当前数在桶中的数量减一,然后 \(ans\) 再加上当前数异或 \(k\) 在数列中存在的个数。
如果你使用数组开桶,则时间复杂度为 \(O(n)\),然而这里我为了防止出现很大很变态的数卡我数组,所以使用的 \(map\),时间复杂度 \(O(n \log n)\)
代码实现:
#include <bits/stdc++.h>
#define debug(x) cerr<<#x<<": "<<x<<endl;
#define int long long
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
namespace Larry76{
const int MAX_SIZE = 1.1e6;
map<int,int>hashtable;
int ori[MAX_SIZE];
void main(){
//Code Here;
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>ori[i];
hashtable[ori[i]]++;
}
int ans = 0;
for(int i=1;i<=n;i++){
hashtable[ori[i]]--;
ans += hashtable[ori[i] ^ k];
}
cout<<ans<<endl;
}
}
signed main(){
#ifdef LOCAL
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
double c1 = clock();
#else
ios::sync_with_stdio(false);
#endif
//============================================
Larry76::main();
//============================================
#ifdef LOCAL
double c2 = clock();
cerr<<"Used Time: "<<c2-c1<<"ms"<<endl;
if(c2-c1>1000)
cerr<<"Warning!! Time Limit Exceeded!!"<<endl;
fclose(stdin);
fclose(stdout);
#endif
return 0;
}
标签:ch,int,题解,个数,CF742B,ori,oplus
From: https://www.cnblogs.com/larry76/p/17130257.html