#include #include #include #include #include #include #include #include #include #include #include #include #include namespace detail { template struct CLP { template inline static constexpr value_type clp(value_type value) noexcept { value = CLP::clp(value); return value | (value >> N); } }; template<> struct CLP<0> { template inline static constexpr value_type clp(value_type value) noexcept { return value; } }; template inline constexpr value_type clp(value_type value) noexcept { return 1 + detail::CLP<(std::numeric_limits::digits / 2)>::clp(value - 1); } }; inline constexpr auto clp(std::uint16_t value) noexcept { return detail::clp(value); } inline constexpr auto clp(std::uint32_t value) noexcept { return detail::clp(value); } inline constexpr auto clp(std::uint64_t value) noexcept { return detail::clp(value); } // inline constexpr std::size_t STCalculateSize(std::size_t arraySize) noexcept { const auto treeSize = (clp(arraySize) << 1) - 1; return treeSize; } template inline void STConstruct( array_iterator arrayBegin, array_iterator arrayEnd, tree_iterator treeBegin, tree_iterator treeIt) { using node_type = typename std::iterator_traits::value_type; assert(arrayBegin != arrayEnd); const auto count = std::distance(arrayBegin, arrayEnd); if (1 == count) { *treeIt = *arrayBegin; } else { auto arrayMiddle = arrayBegin; std::advance(arrayMiddle, (count - 1) / 2 + 1); auto pos = std::distance(treeBegin, treeIt); auto treeLeft = treeIt; std::advance(treeLeft, pos + 1); auto treeRight = treeLeft; std::advance(treeRight, 1); STConstruct(arrayBegin, arrayMiddle, treeBegin, treeLeft); STConstruct(arrayMiddle, arrayEnd, treeBegin, treeRight); *treeIt = node_type::unite(*treeLeft, *treeRight); } } template inline void STConstruct( array_iterator arrayBegin, array_iterator arrayEnd, tree_iterator treeBegin) { STConstruct(arrayBegin, arrayEnd, treeBegin, treeBegin); } template // = typename operation::result_type> struct SegmentTree { template SegmentTree(std::initializer_list il) : SegmentTree(il.begin(), il.end(), il.size()) { } template SegmentTree(const container& c) : SegmentTree(std::cbegin(c), std::cend(c), std::size(c)) { } template SegmentTree(iterator begin, iterator end) : SegmentTree(begin, end, std::distance(begin, end)) { } template SegmentTree(iterator begin, iterator end, std::size_t count) : count(count), nodes(STCalculateSize(count), node_type{}) { STConstruct(begin, end, nodes.begin()); } SegmentTree(const SegmentTree&) = default; SegmentTree(SegmentTree&&) = default; SegmentTree& operator = (const SegmentTree&) = default; SegmentTree& operator = (SegmentTree&&) = default; node_type Query(std::size_t range_low, std::size_t range_high) const noexcept { assert(range_low >= 0); assert(range_high < count); assert(range_low <= range_high); return Query(range_low, range_high, 0, count - 1, 0); } private: node_type Query( std::size_t range_low, std::size_t range_high, std::size_t low, std::size_t high, std::size_t pos) const noexcept { if ((range_low <= low) && (range_high >= high)) { auto it = nodes.cbegin(); std::advance(it, pos); return *it; } else if ((range_low > high) || (range_high < low)) { return node_type{}; } else { const auto middle = low + (high - low) / 2; return node_type::unite( Query(range_low, range_high, low, middle, 2 * pos + 1), Query(range_low, range_high, middle + 1, high, 2 * pos + 2)); } } const std::size_t count; std::vector nodes; }; // int _gcd(int a, int b) { return b == 0 ? a : _gcd(b, a % b); } int gcd(int left, int right) { if (left < 0) { left =-left; } if (right < 0) { right =-right; } return _gcd(left, right); } struct Node { Node() : Node(0) { } Node(int value) : max(value), sum((long long)value), gcd(value) { } static Node unite(const Node& left, const Node& right) { Node node; node.max = std::max(left.max, right.max); node.sum = left.sum + right.sum; node.gcd = ::gcd(left.gcd, right.gcd); return node; } int max; long long sum; int gcd; }; int main() { int n; std::cin >> n; std::vector v(n, 0); for (int i = 0; i != n; ++i) { std::cin >> v[i]; } SegmentTree st(v); for (int low = 0; low != n; ++low) { for (int high = low; high != n; ++high) { const Node result = st.Query(low, high); const long long strange = result.gcd * (result.sum - result.max); std::cout << strange << std::endl; } } return 0; }