Rock and Lever (CodeForces - 1420B)
题意
给出一个数组,求数组中有多少对整数满足:ai & aj ≥ ai ⊕ aj(i < j)
思路
将数组中的元素从小到大进行排序,由&运算与⊕的特点可知,只有当两个最高位相同是才有可能满足题目所描述的情况,排好序后直接计算每一段的组合数即可
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5 + 5;
int a[N];
void solve() {
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
sort(a + 1, a + n + 1);
LL cnt = 0, ans = 0;
for (int i = 2; i <= n; i++) {
if ((a[i] & a[i - 1]) >= (a[i] ^ a[i - 1])) {
cnt++;
ans += cnt;
}
else
cnt = 0;
}
printf("%lld\n", ans);
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
solve();
}
return 0;
}
Nezzar and Symmetric Array (CodeForces - 1478C)
题意
对于一个长度为2n的数组a,每个数本身与其相反数成对地出现在数组中,用数组a构造一个一个数组d,d数组中的元素满足 di=
∑
j
=
1
2
n
∣
a
i
−
a
j
∣
\sum_{j=1}^{2n} |ai−aj|
∑j=12n∣ai−aj∣,现给出一个d数组,问是否存在一个a数组可以构造出该d数组
思路
参考dalao博客
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL a[100005];
void solve() {
int n;
scanf("%d", &n);
bool flag = true;
map<LL, int> mp;
for (int i = 0; i < 2 * n; i++) {
LL k;
scanf("%lld", &k);
if (k & 1)
flag = false;
mp[k]++;
}
int sum = 1;
LL p = 0;
for (auto it : mp) {
if (it.second != 2)
flag = false;
a[sum++] = (it.first) / 2;
}
for (sum--; sum > 0; sum--) {
LL q = a[sum] - p;
if (q % sum)
flag = false;
LL r = q / sum;
p += r;
if (r <= 0)
flag = false;
}
if (!flag)
puts("NO");
else
puts("YES");
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
solve();
}
return 0;
}