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.
n个数字,问有多少对数字加起来刚好是2的k次方。
这还用说?枚举个k再枚举个a[i]然后看看有没有2^k-a[i]这个数就好了
这里我为了防被x没用hash用了二分
不过要考虑一个数字出现很多次的情况,或者你要找的刚好就是这个数的情况
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<ctime>
#define LL long long
#define inf 0x7ffffff
#define pa pair<int,int>
#define pi 3.1415926535897932384626433832795028841971
using namespace std;
inline LL read()
{
LL x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
inline void write(LL a)
{
if (a<){printf("-");a=-a;}
if (a>=)write(a/);
putchar(a%+'');
}
inline void writeln(LL a){write(a);printf("\n");}
int n,sav;
LL ans;
int a[];
int rep[];
int bin[];
inline bool bsearch(int l,int r,int x,int dat)
{
if (dat<=)return ;
if (l>r)return ;
int ans=-;
while (l<=r)
{
int mid=(l+r)>>;
if (a[mid]==dat){ans=mid;break;}
if (a[mid]>dat)r=mid-;
if (a[mid]<dat)l=mid+;
}
sav=ans;
return (ans!=x||ans==x&&rep[x]>)&&a[ans]==dat;
}
int main()
{
n=read();
bin[]=;
for (int i=;i<;i++)bin[i]=bin[i-]*;
for(int i=;i<=n;i++)a[i]=read();
sort(a+,a+n+);
int cur=;
for(int i=;i<=n;i++)
{
if (a[i]!=a[i-])a[++cur]=a[i],rep[cur]=;
else rep[cur]++;
}
n=cur;
for(int i=;i<=n;i++)
{
for (int j=;j<;j++)
if (bsearch(i,n,i,bin[j]-a[i]))
{
if (sav==i)ans+=(LL)rep[i]*(rep[i]-)/;
else ans+=(LL)rep[i]*rep[sav];
}
}
printf("%lld\n",ans);
}
cf702B