You are given n integers a1, a2, ..., an. Find the number of pairs of indexes i, j (i < j) that ai + aj is a power of 2 (i. e. some integer xexists so that ai + aj = 2x).
The first line contains the single positive integer n (1 ≤ n ≤ 105) — the number of integers.
The second line contains n positive integers a1, a2, ..., an (1 ≤ ai ≤ 109).
Print the number of pairs of indexes i, j (i < j) that ai + aj is a power of 2.
4 7 3 2 1
2
3 1 1 1
3
In the first example the following pairs of indexes include in answer: (1, 4) and (2, 4).
In the second example all pairs of indexes (i, j) (where i < j) include in answer.
题意:让你找有多少对儿ai+aj=2^x (x属于lg(a1+a2)~lg(an-1+an)假设a数组是从小到大排列的)
先排下序,然后对j(1~n)从i+1~n找有没有aj满足条件,这个过程可以用二分来实现。复杂度O(nlg(n)*lg(m))吧(不太确定)。
(这段代码自己感觉写的好矬。。)
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#include<map>
using namespace std;
int a[101000];
#define ll long long
map<int,int>mapp;
map<int,int>use;
int lg2(ll x)
{
ll s=1;
int cnt=0;
while (s*2<=x)
{
s*=2;
cnt++;
}
return cnt;
}
int _2n(int x)
{
int s=1;
for (int i=1;i<=x;i++)
{
s*=2;
}
return s;
}
int main()
{
int n;
scanf("%d",&n);
mapp.clear();
use.clear();
for (int i=1;i<=n;i++) {scanf("%d",&a[i]); mapp[a[i]]++;}
sort(a+1,a+n+1); int rl=lg2(a[1]+a[2]);int rr=lg2(a[n]+a[n-1]);
ll ans=0;
for (int i=1;i<=n;i++)
{
for (int j=rl;j<=rr;j++)
{
int l=i;int r=n; int ta=_2n(j);
int fi=ta-a[i];
if (fi>0)
{
while (r-l>1)
{
int mid=(l+r)/2;
if (fi<=a[mid]) r=mid;
else l=mid;
}
if (a[i]+a[r]==ta) {
if (a[i]==a[r])
{ans=ans+mapp[a[r]]-use[a[r]]-1;use[a[r]]++;}
else {ans=ans+mapp[a[r]];}
}
}
}
}
printf("%I64d",ans);
}