题目链接
题解
题意
找到数组中满足
i
<
j
i<j
i<j 且
(
a
i
(a_i
(ai &
a
j
)
a_j)
aj)
≤
(
a
i
⨁
a
j
)
\leq (a_i \bigoplus a_j)
≤(ai⨁aj)的pair
的数量。
思路
当
a
i
a_i
ai和
a
j
a_j
aj的二进制表示的最高位位置相同且为1
时,可以满足上述条件。
- 最高位的
1
相与之后得到1
; - 最高位的
1
异或之后得到0
(异或可以看作不进位的加法)。
求数量可以在观察之后可以得出等差数列的做法。
AC代码
#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize(2)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ull unsigned long long
#define ll long long
#define rep(i, x, y) for(int i=x;i<=y;i++)
#define mms(x, n) memset(x, n, sizeof(x))
#define mmc(A, tree) memcpy(A, tree, sizeof(tree))
#define eps (1e-8)
#define PI (acos(-1.0))
#define INF (0x3f3f3f3f)
#define mod (ll)(1e9+7)
typedef pair<int, int> P;
int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
map<ll, int> mp;
rep(i, 1, n) {
ll t;
cin >> t;
int cnt = 0;
for (int i = 1; i <= 30; i++) {
if (t >> 1) cnt = i;
t >>= 1;
if (t == 0) break;
}
mp[cnt] += 1;
}
ll ans = 0;
for (auto it : mp) {
ll tmp = it.second;
if (tmp >= 2) {
if (tmp & 1) ans += (tmp - 1) / 2 * tmp;
else ans += (tmp) / 2 * (tmp - 1);
}
}
cout << ans << endl;
}
return 0;
}
之后的代码
看完大佬的代码之后我悟了!
#include <bits/stdc++.h>
using namespace std;
//#pragma GCC optimize(2)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ull unsigned long long
#define ll long long
#define rep(i, x, y) for(int i=x;i<=y;i++)
#define mms(x, n) memset(x, n, sizeof(x))
#define mmc(A, tree) memcpy(A, tree, sizeof(tree))
#define eps (1e-8)
#define PI (acos(-1.0))
#define INF (0x3f3f3f3f)
#define mod (ll)(1e9+7)
typedef pair<int, int> P;
int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif
int n, x;
int t[40];
ll ans = 0;
for (cin >> n; cin >> n; cout << ans << ' ') {
ans = 0;
rep(i, 0, 30) t[i] = 0;
rep(i, 1, n) {
cin >> x;
for (int i = 30; i >= 0; i--) if (x & (1 << i)) {t[i] += 1; break;}
}
rep(i, 0, 30) if (t[i] >= 2) ans += 1LL * (t[i] - 1) * t[i] / 2LL;
}
return 0;
}