double operator[](double x) const { assert(!curve_.empty()); AbstractCurvePoint xpt(x); if (xpt <= *curve_.begin()) { return static_cast<double>(*curve_.begin()); } if (xpt >= *curve_.rbegin()) { return static_cast<double>(*curve_.rbegin()); } auto it_max = curve_.upper_bound(xpt); assert(!((*it_max) <= xpt)); assert(xpt != (*it_max)); assert(xpt < (*it_max)); auto it_min = std::prev(it_max, 1); assert(!((*it_min) > xpt)); assert((*it_min) <= xpt); assert((*it_min) < (*it_max)); assert((*it_min) != (*it_max)); if (xpt == (*it_min)) { return static_cast<double>(*it_min); } return (*it_min).interpolate(*it_max, x); }
/// Mark the given indices (ToMark) as safe in the given set of indices /// (Safe). Marking safe usually means adding ToMark to Safe. However, if there /// is already a prefix of Indices in Safe, Indices are implicitely marked safe /// already. Furthermore, any indices that Indices is itself a prefix of, are /// removed from Safe (since they are implicitely safe because of Indices now). static void MarkIndicesSafe(const ArgPromotion::IndicesVector &ToMark, std::set<ArgPromotion::IndicesVector> &Safe) { std::set<ArgPromotion::IndicesVector>::iterator Low; Low = Safe.upper_bound(ToMark); // Guard against the case where Safe is empty if (Low != Safe.begin()) Low--; // Low is now the last element smaller than or equal to Indices. This // means it points to a prefix of Indices (possibly Indices itself), if // such prefix exists. if (Low != Safe.end()) { if (IsPrefix(*Low, ToMark)) // If there is already a prefix of these indices (or exactly these // indices) marked a safe, don't bother adding these indices return; // Increment Low, so we can use it as a "insert before" hint ++Low; } // Insert Low = Safe.insert(Low, ToMark); ++Low; // If there we're a prefix of longer index list(s), remove those std::set<ArgPromotion::IndicesVector>::iterator End = Safe.end(); while (Low != End && IsPrefix(ToMark, *Low)) { std::set<ArgPromotion::IndicesVector>::iterator Remove = Low; ++Low; Safe.erase(Remove); } }
/// Checks if Indices, or a prefix of Indices, is in Set. static bool PrefixIn(const ArgPromotion::IndicesVector &Indices, std::set<ArgPromotion::IndicesVector> &Set) { std::set<ArgPromotion::IndicesVector>::iterator Low; Low = Set.upper_bound(Indices); if (Low != Set.begin()) Low--; // Low is now the last element smaller than or equal to Indices. This means // it points to a prefix of Indices (possibly Indices itself), if such // prefix exists. // // This load is safe if any prefix of its operands is safe to load. return Low != Set.end() && IsPrefix(*Low, Indices); }
long int nextPrime(long int after) { auto upperBound = primes.upper_bound(after); if (upperBound != primes.end()) { return *upperBound; } long int primeCandidate = after + after % 2 + 1; // next odd for (; !isPrime(primeCandidate); primeCandidate += 2) { } return primeCandidate; }
void MemoryObjectStoreCursor::setReverseIteratorFromRemainingRange(std::set<IDBKeyData>& set) { if (!set.size()) { m_iterator = Nullopt; return; } if (m_remainingRange.isExactlyOneKey()) { m_iterator = set.find(m_remainingRange.lowerKey); if (*m_iterator == set.end()) m_iterator = Nullopt; return; } if (!m_remainingRange.upperKey.isValid()) { m_iterator = --set.end(); if (!m_remainingRange.containsKey(**m_iterator)) m_iterator = Nullopt; return; } m_iterator = Nullopt; // This is one record past the actual key we're looking for. auto highest = set.upper_bound(m_remainingRange.upperKey); if (highest == set.begin()) return; // This is one record before that, which *is* the key we're looking for. --highest; if (m_remainingRange.upperOpen && *highest == m_remainingRange.upperKey) { if (highest == set.begin()) return; --highest; } if (!m_remainingRange.lowerKey.isNull()) { if (highest->compare(m_remainingRange.lowerKey) < 0) return; if (m_remainingRange.lowerOpen && *highest == m_remainingRange.lowerKey) return; } m_iterator = highest; }
int main(){ //insert O(log N) per element or O(1) am per element for _sorted_ elements //For a total of O(N log N) or O(N) for sorted inputs int key; for(key = 0; key < 10; key++){ myset.insert(key); } //find O(log N) it = myset.find(3); //removes 3 in O(1) am post-find time myset.erase(it); //removes 4 from the set O(log N) time myset.erase(4); //iterate the set in forward order O(1) am / O(log N) //for a total of O(N) total //Note that begin() returns an iterator to the first element //whereas that end() returns to a dummy element after the last element for(it = myset.begin(); it != myset.end(); it++){ std::cout << *it << " " ; } std::cout << std::endl; //iterate the set in reverse order )O(1) am / O(log N) //for a total of O(N) total //Note that rbegin() returns an iterator to the last element //whereas that end() returns to a dummy element before the first element for(rit = myset.rbegin(); rit != myset.rend(); rit++){ std::cout << *rit << " " ; } std::cout << std::endl; //Find the first element greater than or equal to the current element in O(log N) time //In this case it returns 6 it = myset.lower_bound(6); std::cout << *it << std::endl; //Find the first element greater than the current element in O(log N) time //In this case it returns 7 it = myset.upper_bound(6); std::cout << *it << std::endl; // Empties the set O(N) time myset.clear(); }
int main() { //freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout); //std::ios::sync_with_stdio(0); int c, n; scanf("%d %d", &c, &n); for (int i = 1; i <= n; ++i) scanf("%d", a + i); m.insert(0); for (int i = 1; i <= n; ++i) { p = m; for (std::set<int>::iterator it = p.begin(); it != p.end(); ++it) m.insert(*it + a[i]); } printf("%d", *(--m.upper_bound(c))); }
std::set<IDBKeyData>::reverse_iterator MemoryObjectStoreCursor::firstReverseIteratorInRemainingRange(std::set<IDBKeyData>& set) { if (m_remainingRange.isExactlyOneKey()) { auto iterator = set.find(m_remainingRange.lowerKey); if (iterator == set.end()) return set.rend(); return --std::set<IDBKeyData>::reverse_iterator(iterator); } if (!m_remainingRange.upperKey.isValid()) return set.rbegin(); // This is one record past the actual key we're looking for. auto highest = set.upper_bound(m_remainingRange.upperKey); // This is one record before that, which *is* the key we're looking for. auto reverse = std::set<IDBKeyData>::reverse_iterator(highest); if (reverse == set.rend()) return reverse; if (m_remainingRange.upperOpen && *reverse == m_remainingRange.upperKey) { ++reverse; if (reverse == set.rend()) return reverse; } if (!m_remainingRange.lowerKey.isNull()) { if (reverse->compare(m_remainingRange.lowerKey) < 0) return set.rend(); if (m_remainingRange.lowerOpen && *reverse == m_remainingRange.lowerKey) return set.rend(); } return reverse; }
// 左对齐 PBLOBNBOX LineFinder::findAlignedBlob(const AlignedBlobParams& p, std::set<PBLOBNBOX, BoxCmp_LT<BLOBNBOX>>& bset, PBLOBNBOX bbox){ if (bbox == nullptr) return nullptr; int dx = p.vertical.x, dy = p.vertical.y; int dir_y = dy < 0 ? -1 : 1; int skew_tolerance = p.max_v_gap / jun::kMaxSkewFactor; int x2 = (p.max_v_gap*dx + dy / 2) / dy; Rect box = bbox->bounding_box(); int x_start = box.x; x2 += x_start; int xmin, xmax, ymin, ymax; if (x2 < x_start){ //向左 xmin = x2; xmax = x_start; } else{ xmin = x_start; xmax = x2; } if (dy > 0){ //向下 ymin = box.ylast(); ymax = ymin + p.max_v_gap; } else{ ymax = box.y; ymin = ymax - p.max_v_gap; } xmin -= skew_tolerance - p.min_gutter; xmax += skew_tolerance + p.r_align_tolerance; logger()->debug("Starting {} {} search at {}-{},{} dy={} search_size={}, gutter={}\n", p.ragged ? "Ragged" : "Aligned", "Left", xmin, xmax, box.ylast(), dir_y, p.max_v_gap, p.min_gutter ); auto begin_blob = std::make_shared<BLOBNBOX>(); begin_blob->set_bounding_box(Rect{ xmin, ymin, 1, 1 }); auto end_blob = std::make_shared<BLOBNBOX>(); end_blob->set_bounding_box(Rect{ xmax, ymax, 1, 1 }); auto beginIter = bset.lower_bound(begin_blob); auto endIter = bset.upper_bound(end_blob); PBLOBNBOX result = nullptr; int min_dist = std::numeric_limits<int>::max(); for (auto iter = beginIter; iter != endIter; ++iter){ Rect nbox = (*iter)->bounding_box(); int n_y = (nbox.y + nbox.ylast()) / 2; if ((dy > 0) && (n_y<ymin || n_y>ymax)) continue; if (dy < 0 && (n_y < ymin || n_y > ymax)) continue; int x_at_ny = x_start + (n_y - ymin)*dx / dy; int n_x = nbox.x; //aligned so keep it. if (n_x <= x_at_ny + p.r_align_tolerance&&n_x >= x_at_ny - p.l_align_tolerance){ logger()->debug("aligned, seeking left, box={}\n", nbox); TabType n_type = (*iter)->left_tab_type; if (n_type != TabType::TT_NONE && (p.ragged || n_type != TabType::TT_MAYBE_RAGGED)){ int x_dist = n_x - x_at_ny; int y_dist = n_y - ymin; int new_dist = x_dist*x_dist + y_dist*y_dist; if (new_dist < min_dist) { min_dist = new_dist; result = (*iter); } } } } return result; }