Problem:
Score : 600 points

Problem Statement

Takahashi has N balls with positive integers written on them. The integer written on the i-th ball is A_i.
He would like to form some number of pairs such that the sum of the integers written on each pair of balls is a power of 2.
Note that a ball cannot belong to multiple pairs.
Find the maximum possible number of pairs that can be formed.

Here, a positive integer is said to be a power of 2 when it can be written as 2^t using some non-negative integer t.

Constraints

1 \leq N \leq 2\times 10^5

1 \leq A_i \leq 10^9

A_i is an integer.

Input

Input is given from Standard Input in the following format:

N
A_1 A_2 ... A_N

Output

Print the maximum possible number of pairs such that the sum of the integers written on each pair of balls is a power of 2.

Sample Input 1

3
1 2 3

Sample Output 1

1

We can form one pair whose sum of the written numbers is 4 by pairing the first and third balls.
Note that we cannot pair the second ball with itself.

Sample Input 2

5
3 11 14 5 13

Sample Output 2

2

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;

public class AtCoder
{
    public static void Main()
    {
        int n;
        n = int.Parse(Console.ReadLine().Trim());
        string[] s;
        s = Console.ReadLine().Trim().Split(' ');
        int[] a = new int[n];
        for (int i = 0; i < n; i++)
        {
            a[i] = int.Parse(s[i]);
        }
        Array.Sort(a);
        int[] b = new int[n];
        int x = 1;
        int ans = 0;
        bool fsuc = true;
        int y = (int)Math.Pow(2, 30);
        BinarySearch f = new BinarySearch(a);
        for (int i = n - 1; i > -1; i--)
        {
            if (b[i] == 1) continue;
            while (y / 2 > a[i])
            {
                y /= 2;
            }
            x = y - a[i];
            for (int j = f.UpperBound(x, i) - 1; j > -1; j--)
            {
                if (a[j] == x)
                {
                    if (b[j] == 0)
                    {
                        if (i != j)
                        {
                            b[i] = 1;
                            b[j] = 1;
                            ans++;
                            while (false)
                            {
                                if (i > 0 && j > 0)
                                {
                                    if ((a[i - 1] == a[i]) && (a[j - 1] == x)
                                        && (b[i - 1] == 0) && (b[j - 1] == 0))
                                    {
                                        i--;
                                        j--;
                                        b[i] = 1;
                                        b[j] = 1;
                                        ans++;
                                    }
                                    else fsuc = false;
                                }
                                else fsuc = false;
                            }
                            fsuc = true;
                            break;
                        }
                    }
                }
                if (a[j] < x) j = -1;
            }
        }
        Console.WriteLine(ans);
    }
}

public class BinarySearch
{

    int[] a;
    public BinarySearch(int[] arr)
    {
        a = arr;
    }

    public int LowerBound(int x, int i)
    {
        int l = -1;
        int r = i;
        while (r - l > 1)
        {
            int m = l + (r - l) / 2;
            if (a[m] >= x) r = m;
            else l = m;
        }
        return r;
    }

    public int UpperBound(int x, int i)
    {
        int l = -1;
        int r = i;
        while (r - l > 1)
        {
            int m = l + (r - l) / 2;
            if (a[m] > x) r = m;
            else l = m;
        }
        return r;
    }
}