需要推导出来一个等式
这个等式是符合要求的数对,用map来统计每种符合要求的数对中数的个数。然后再从每一种数对里面符合要求数中求组合数就ok了,例如符合要求的数有3个,那么就任意从三个里面去出两个来,组合数个数就是数对的个数。 组合数是从n个数中取出m个 C(n,m)
#include<bits/stdc++.h>
using namespace std;
const int M = 2e5 + 5;
typedef long long ll;
ll a[M];
ll ans;
inline void deal() {
map< pair<ll, ll>, ll> mp;
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i];
int tmp = a[i];
while (a[i] % 2 == 0) {
a[i] /= 2;
}
mp[{tmp - log2(tmp / a[i]), a[i]}]++;
}
ans = 0;
for (auto &it : mp) {
if (it.second >= 2) {
ans += it.second * (it.second - 1) / 2;
}
}
}
int main() {
int t;
cin >> t;
while (t--) {
deal();
cout << ans << endl;
}
}