-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathLC_711_CountGoodMeals.cpp
93 lines (80 loc) · 2.37 KB
/
LC_711_CountGoodMeals.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
https://leetcode.com/problems/count-good-meals/
1711. Count Good Meals
*/
const int MOD = 1e9+7;
static auto speedup = [](){
ios_base::sync_with_stdio(false);
cout.tie(NULL);
cin.tie(NULL);
return NULL;
}();
class Solution {
public:
/*
int countPairs_1(vector<int>& deliciousness) {
int n = deliciousness.size();
vector<long long> power2(22);
unordered_map<int,int> umap;
int ans=0, need=0, curr=0;
//min pow of 2 = 0
//max pow of 2 = 2^21;
for(int i=0; i<22; i++)
power2[i] = 1<<i;
for(int dl: deliciousness)
{
for(int p2: power2)
{
need = p2-dl;
if(umap.find(need)!=umap.end())
ans= (ans + umap[need])%MOD;
}
umap[dl]++;
}
return ans;
}//end
*/
int countPairs(vector<int>& deliciousness) {
unordered_map<int,long long> umap;
int max_dl=0, need=0;
int ans=0;
for(int dl: deliciousness)
{
umap[dl]++;
max_dl = max(max_dl, dl);
}
if(max_dl == 0) return 0; // if all deliciousness is zero
max_dl<<=1; //how many powers we need one extra than max dl
int pow2size = ceil(log2(max_dl))+1;
// int pow2size =0;
// while(max_dl)
// {
// pow2size++;
// max_dl>>=1;
// }
// cout<<max_dl<<endl;
// cout<<pow2size<<endl;
int *power = new int[pow2size];
power[0]=1;
for(int i=1; i<pow2size; i++)
power[i] = power[i-1]<<1;
for(auto &[dl, dl_freq]: umap)
{
for(int p=pow2size-1; p>=0; p--)
{
need = power[p]-dl;
// cout<<dl<<" "<<dl_freq<<"] ->"<<need<<" "<<power[p]<<endl;
if(need < dl) break; // to avoid duplicates counting
if(umap.find(need)!=umap.end())
{
if(dl == need)
ans = (ans + (dl_freq*(dl_freq-1))/2)%MOD;
else
ans = (ans + dl_freq*umap[need])%MOD;
}
// cout<<" ans "<<ans<<endl;
}
}
return ans;
}//end
};