#include "molecules.h"
#include <map>
#include <deque>
#include <vector>
#include <algorithm>
//#include <iostream>
using namespace std;
typedef pair<int,int> pii;
/*
4 15 17
6 8 8 7
=>2
=>2 3
4 15 17
4 6 6 5
=>3
=> 1 3 0
4 14 15
5 5 6 6
=>0
4 10 20
15 17 16 18
=>1
=>3
4 0 0
0 0 0 0
=>1
=>3
*/
vector<int> find_subset(int l, int u, vector<int> w) {
const int& N = w.size();
const int& UpperBound = u;
const int& LowerBound = l;
vector<pii> wVtr(N);
for(int i = 0; i < N; ++i)
wVtr[i] = pii(w[i], i);
sort(wVtr.begin(), wVtr.end());
while(!wVtr.empty() && wVtr.front().first > UpperBound) wVtr.pop_back();
if(wVtr.empty()) return vector<int>(0);
if(l <= wVtr.back().first && wVtr.back().first <= UpperBound) return vector<int>(1,wVtr.back().second);
if(accumulate(w.begin(),w.end(),0) < l) return vector<int>(0);
reverse(wVtr.begin(),wVtr.end());
// cout << "w:";
// for(const auto& i:w) cout << i << " ";
// cout << endl;
map<int,deque<int>> PossibleNumbers_left;{
PossibleNumbers_left[0] = deque<int>();
deque<pair<int,deque<int>>> ToInsert;
for(int i = 0; i < N/2; ++i){
const pii& w_i = wVtr[i];
for(const auto& n:PossibleNumbers_left)
if(n.first+w_i.first <= UpperBound){
ToInsert.push_back(n);
ToInsert.back().first += w_i.first;
ToInsert.back().second.push_back(w_i.second);
}
while(!ToInsert.empty()){
PossibleNumbers_left[ToInsert.back().first] = ToInsert.back().second;
ToInsert.pop_back();
}
const auto& W = PossibleNumbers_left.rbegin();
if(LowerBound <= W->first && W->first <= UpperBound)
return vector<int>(W->second.begin(),W->second.end());
}
// cout << "PossibleNumbers_left:" << endl;
// for(const auto& n:PossibleNumbers_left){
// cout << n.first << ": ";
// for(const auto& m:n.second) cout << m << " ";
// cout << endl;
// }cout << endl;
}
map<int,deque<int>> PossibleNumbers_right;{
PossibleNumbers_right[0] = deque<int>();
deque<pair<int,deque<int>>> ToInsert;
for(int i = N/2; i < N; ++i){
const pii& w_i = wVtr[i];
for(const auto& n:PossibleNumbers_right)
if(n.first+w_i.first <= UpperBound){
ToInsert.push_back(n);
ToInsert.back().first += w_i.first;
ToInsert.back().second.push_back(w_i.second);
}
while(!ToInsert.empty()){
PossibleNumbers_right[ToInsert.back().first] = ToInsert.back().second;
ToInsert.pop_back();
}
const auto& W = PossibleNumbers_right.rbegin();
if(LowerBound <= W->first && W->first <= UpperBound)
return vector<int>(W->second.begin(),W->second.end());
}
// cout << "PossibleNumbers_right:" << endl;
// for(const auto& n:PossibleNumbers_right){
// cout << n.first << ": ";
// for(const auto& m:n.second) cout << m << " ";
// cout << endl;
// }cout << endl;
}
for(const auto& p:PossibleNumbers_left){
int ToFind = LowerBound - p.first;
auto it = PossibleNumbers_right.lower_bound(ToFind);
if(LowerBound <= p.first + it->first && p.first + it->first <= UpperBound){
vector<int> ret(p.second.begin(), p.second.end());
ret.insert(ret.end(), it->second.begin(), it->second.end());
return ret;
}
}
return vector<int>(0);
}
Compilation message
molecules.cpp: In function 'std::vector<int> find_subset(int, int, std::vector<int>)':
molecules.cpp:55:8: error: 'accumulate' was not declared in this scope
if(accumulate(w.begin(),w.end(),0) < l) return vector<int>(0);
^~~~~~~~~~