题解 CF742B
题目大意:
给定 \(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;
}

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号