J—硝基甲苯之袭
题目链接:https://ac.nowcoder.com/acm/contest/95323/J
题意:
给定一个长度为n的数组,从中挑选两个数ai,aj(i<j),使其ai xor aj == gcd(ai,aj).求总方案数
思路:
由按位异或运算自反性可知,其实是求 ai xor gcd(ai,aj)== aj
aj通过枚举ai的因子(gcd必定是ai因子)来获得,再检查ai,aj的gcd是否是所枚举的因子即可
先求出顺序对+逆序对的总数,将其除以2便是答案
时间复杂度o(n*sqrt(n))
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main() {
ios::sync_with_stdio(false), cin.tie(0);
int n;
cin >> n;
map<int, int> mp;
for (int i = 0; i < n; ++i) {
int x;
cin >> x;
mp[x]++;
}
ll ans = 0;
for (auto &it : mp) {
int x = it.first;
// 处理所有因数i
for (int i = 1; i * i <= x; ++i) {
if (x % i != 0) continue;
// 检查i对应的y
int y = x ^ i;
if (mp.count(y) && __gcd(x, y) == i) {
ans += (ll)it.second * mp[y];
}
// 检查另一个因数k = x/i
int k = x / i;
if (k == i) continue; // 避免重复处理
y = x ^ k;
if (mp.count(y) && __gcd(x, y) == k) {
ans += (ll)it.second * mp[y];
}
}
}
cout << ans/2;
return 0;
}

浙公网安备 33010602011771号