<p>A <strong>good meal</strong> is a meal that contains <strong>exactly two different food items</strong> with a sum of deliciousness equal to a power of two.</p>

<p>You can pick <strong>any</strong> two different foods to make a good meal.</p>

<p>Given an array of integers <code>deliciousness</code> where <code>deliciousness[i]</code> is the deliciousness of the <code>i<sup>​​​​​​th</sup>​​​​</code>​​​​ item of food, return <em>the number of different <strong>good meals</strong> you can make from this list modulo</em> <code>10<sup>9</sup> + 7</code>.</p>

<p>Note that items with different indices are considered different even if they have the same deliciousness value.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> deliciousness = [1,3,5,7,9]
<strong>Output:</strong> 4
<strong>Explanation: </strong>The good meals are (1,3), (1,7), (3,5) and, (7,9).
Their respective sums are 4, 8, 8, and 16, all of which are powers of 2.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> deliciousness = [1,1,1,3,3,3,7]
<strong>Output:</strong> 15
<strong>Explanation: </strong>The good meals are (1,1) with 3 ways, (1,3) with 9 ways, and (1,7) with 3 ways.</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= deliciousness.length &lt;= 10<sup>5</sup></code></li>
	<li><code>0 &lt;= deliciousness[i] &lt;= 2<sup>20</sup></code></li>
</ul>

class Solution {
public:
    unsigned nChoosek(unsigned n, unsigned k) {
        if (k > n) return 0;
        if (k * 2 > n) k = n - k;
        if (k == 0) return 1;

        int result = n;
        for (int i = 2; i <= k; ++i) {
            result *= (n - i + 1);
            result /= i;
        }
        return result;
    }

    int countPairs(vector<int>& deliciousness) {
        int n = deliciousness.size();

        map<int, int> mp;
        // for (auto d : deliciousness) mp[d]++;

        int ops = 0;
        // for (auto it : mp) {
        //     for (int x = 0; x < 22; x++) {
        //         int needed = pow(2, x) - it.first;
        //         if (mp[needed]) {
        //             if (needed == it.first) ops += nChoosek(mp[needed], 2);
        //             else ops += (mp[it.first] * mp[needed]);
        //             break;
        //         }
        //     }

        //     cout << it.first << " " << ops << endl;
        // }
        int MOD = 1e9+7;
        for(int i = 0; i < deliciousness.size(); i++) {
            for(int x = 0; x < 22; x++) {
                int needed = pow(2, x) - deliciousness[i];
                if(mp[needed]) {
                    ops += mp[needed];
                    ops %= MOD;
                } 
            } mp[deliciousness[i]]++;
        }

        return ops;
    }
};
173061