题目连接:http://www.codeforces.com/problemset/problem/702/B
题意:给定n个数,判断有多少个数对(i, j)满足存在x且
ai+aj=2x
。其中
1≤n≤105
,
1≤ai≤109
。
想法:由于
1≤ai≤109
,故我们可枚举x,再查询
2x−ai
是否存在。其中查询过程可二分,所以复杂度为
O(32∗n∗logn)
,若我们记录下最大两个数的和,那么可进一步优化到
O(d∗n∗logn)
,其中
d=log(an−1+an−2)
。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
typedef long long ll;
const int MAXN = 100000 + 10;
int a[MAXN];
int main(){
std::ios::sync_with_stdio(false);
int n;
while(std::cin >> n){
for(int i = 0; i < n; ++i){
std::cin >> a[i];
}
if(n == 1){
puts("0");
continue;
}
std::sort(a, a + n);
ll ans = 0;//可能会超int
int k = log(a[n - 1] + a[n - 2]) / log(2) + 1;
for(int i = 0; i < n; ++i){
for(int j = 0; j <= k; ++j){
int t = (1 << j) - a[i];
if(t > 0){
int l = std::lower_bound(a + i + 1, a + n, t) - a;
int r = std::upper_bound(a + i + 1, a + n, t) - a;
if(r > l){
ans += r - l;
}
}
}
}
std::cout << ans << std::endl;
}
return 0;
}