Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <algorithm>
- #include <vector>
- #include <functional>
- #include <stdint.h>
- namespace HeapSort {
- template<typename T>
- struct StdSwap {
- void operator()(T &a, T &b) {
- std::swap(a, b);
- }
- };
- template<typename T, typename Compare = std::less<T>, typename Swap = StdSwap<T> >
- class Heap {
- public:
- explicit Heap(Compare compare, Swap swap)
- : comparator_(compare), swap_(swap) { }
- void Insert(const T &value) {
- data_.push_back(value);
- ShiftUp(data_.size() - 1);
- }
- void Erase(const int index) {
- swap_(data_[index], data_[data_.size() - 1]);
- data_.pop_back();
- if (index != data_.size()) {
- ShiftDown(index);
- ShiftUp(index);
- }
- }
- void PopMax() {
- Erase(0);
- }
- int GetSize() const {
- return data_.size();
- }
- private:
- static int ComputeLeftSonIndex(const int index) {
- return 2 * index + 1;
- }
- static int ComputeRightSonIndex(const int index) {
- return 2 * index + 2;
- }
- static int ComputeParentIndex(const int index) {
- return (index - 1) / 2;
- }
- void ShiftDown(const int index) {
- int max = index;
- if (ComputeLeftSonIndex(index) < data_.size()
- && comparator_(data_[max], data_[ComputeLeftSonIndex(index)])) {
- max = ComputeLeftSonIndex(index);
- }
- if (ComputeRightSonIndex(index) < data_.size()
- && comparator_(data_[max], data_[ComputeRightSonIndex(index)])) {
- max = ComputeRightSonIndex(index);
- }
- if (max != index) {
- swap_(data_[index], data_[max]);
- ShiftDown(max);
- }
- }
- void ShiftUp(const int index) {
- if (index && comparator_(data_[ComputeParentIndex(index)], data_[index])) {
- swap_(data_[ComputeParentIndex(index)], data_[index]);
- ShiftUp(ComputeParentIndex(index));
- }
- }
- std::vector<T> data_;
- Compare comparator_;
- Swap swap_;
- };
- template<typename T, typename Compare, typename Swap>
- Heap<T, Compare, Swap> MakeHeap(Compare compare, Swap swap) {
- return Heap<T, Compare, Swap>(compare, swap);
- }
- template<typename ForwardIterator>
- struct IteratorSwap {
- void operator()(ForwardIterator &first, ForwardIterator &second) {
- std::swap(*first, *second);
- }
- };
- template<typename ForwardIterator, typename Compare>
- struct IteratorCompare {
- private:
- Compare cmp;
- public:
- IteratorCompare(Compare _cmp) : cmp(_cmp) { }
- bool operator()(ForwardIterator a, ForwardIterator b) {
- return cmp(*a, *b);
- }
- };
- template<typename ForwardIterator, typename Compare>
- void Sort(ForwardIterator begin, ForwardIterator end, Compare compare =
- [](ForwardIterator first, ForwardIterator second) {
- return *first < *second;
- }
- ) {
- auto heap = MakeHeap<ForwardIterator>(
- IteratorCompare<ForwardIterator, Compare>(compare),
- IteratorSwap<ForwardIterator>()
- );
- for (auto it = begin; it != end; ++it)
- heap.Insert(it);
- while (heap.GetSize()) {
- heap.PopMax();
- }
- }
- }
- struct FootballPlayer {
- int efficiency;
- int id;
- explicit FootballPlayer(const int efficiency = 0, const int id = 0) {
- this->efficiency = efficiency;
- this->id = id;
- }
- };
- static bool IsFootballPlayerLessEfficient(const FootballPlayer &first,
- const FootballPlayer &second) {
- if (first.efficiency < second.efficiency) {
- return true;
- }
- if (first.efficiency > second.efficiency) {
- return false;
- }
- return (first.id < second.id);
- }
- static bool IsFootballPlayerHasLessId(const FootballPlayer &first,
- const FootballPlayer &second) {
- if (first.id < second.id) {
- return true;
- }
- return false;
- }
- std::vector<FootballPlayer> FindMostEfficientSolidarityTeam(std::vector<FootballPlayer> players) {
- HeapSort::Sort(players.begin(), players.end(), IsFootballPlayerLessEfficient);
- std::vector<FootballPlayer>::iterator left = players.begin();
- std::vector<FootballPlayer>::iterator right = left + 1;
- std::vector<FootballPlayer>::iterator end = players.end();
- std::vector<FootballPlayer>::iterator save_left = left;
- std::vector<FootballPlayer>::iterator save_right = right;
- int64_t save_sum;
- int64_t sum = save_sum = left->efficiency;
- while (right != end) {
- while (right != end && 1ll * (left->efficiency) +
- (left + 1)->efficiency >= right->efficiency) {
- sum += right->efficiency;
- right++;
- }
- if (sum > save_sum) {
- save_sum = sum, save_left = left, save_right = right;
- }
- sum -= left->efficiency;
- left++;
- }
- std::vector<FootballPlayer> most_efficient_team;
- while (save_left != save_right) {
- most_efficient_team.push_back(*save_left);
- save_left++;
- }
- HeapSort::Sort(most_efficient_team.begin(), most_efficient_team.end(), IsFootballPlayerHasLessId);
- return most_efficient_team;
- }
- int64_t FindTotalEffeciency(const std::vector<FootballPlayer> &team) {
- int64_t sum = 0;
- for (int i = 0; i < team.size(); ++i) {
- sum += team[i].efficiency;
- }
- return sum;
- }
- std::vector<FootballPlayer> InputPlayers(std::istream &input_stream) {
- int number;
- input_stream >> number;
- std::vector<FootballPlayer> players(0);
- for (int i = 0; i < number; ++i) {
- int efficiency;
- input_stream >> efficiency;
- players.push_back(FootballPlayer(efficiency, i));
- }
- return players;
- }
- void OutputMostEffecientTeam(const std::vector<FootballPlayer> &team,
- std::ostream &output_stream) {
- output_stream << FindTotalEffeciency(team) << std::endl;
- for (int i = 0; i < team.size(); ++i) {
- output_stream << team[i].id + 1 << " ";
- }
- output_stream << std::endl;
- }
- int main() {
- std::vector<FootballPlayer> players = InputPlayers(std::cin);
- std::vector<FootballPlayer> most_efficient_team = FindMostEfficientSolidarityTeam(players);
- OutputMostEffecientTeam(most_efficient_team, std::cout);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement