Submission #938955

#TimeUsernameProblemLanguageResultExecution timeMemory
938955riaritiModsum (NOI12_modsum)C++17
0 / 25
3 ms3708 KiB
#line 1 "MODSUM.cpp" #include <bits/stdc++.h> #line 7 "MODSUM.cpp" #ifdef _MSC_VER #include <intrin.h> #endif #if __cplusplus >= 202002L #include <bit> #endif namespace atcoder { namespace internal { #if __cplusplus >= 202002L using std::bit_ceil; #else unsigned int bit_ceil(unsigned int n) { unsigned int x = 1; while (x < (unsigned int)(n)) x *= 2; return x; } #endif int countr_zero(unsigned int n) { #ifdef _MSC_VER unsigned long index; _BitScanForward(&index, n); return index; #else return __builtin_ctz(n); #endif } constexpr int countr_zero_constexpr(unsigned int n) { int x = 0; while (!(n & (1 << x))) x++; return x; } } // namespace internal } // namespace atcoder namespace atcoder { #if __cplusplus >= 201703L template <class S, auto op, auto e, class F, auto mapping, auto composition, auto id> struct lazy_segtree { static_assert(std::is_convertible_v<decltype(op), std::function<S(S, S)>>, "op must work as S(S, S)"); static_assert(std::is_convertible_v<decltype(e), std::function<S()>>, "e must work as S()"); static_assert( std::is_convertible_v<decltype(mapping), std::function<S(F, S)>>, "mapping must work as F(F, S)"); static_assert( std::is_convertible_v<decltype(composition), std::function<F(F, F)>>, "compostiion must work as F(F, F)"); static_assert(std::is_convertible_v<decltype(id), std::function<F()>>, "id must work as F()"); #else template <class S, S (*op)(S, S), S (*e)(), class F, S (*mapping)(F, S), F (*composition)(F, F), F (*id)()> struct lazy_segtree { #endif public: lazy_segtree() : lazy_segtree(0) {} explicit lazy_segtree(int n) : lazy_segtree(std::vector<S>(n, e())) {} explicit lazy_segtree(const std::vector<S> &v) : _n(int(v.size())) { size = (int)internal::bit_ceil((unsigned int)(_n)); log = internal::countr_zero((unsigned int)size); d = std::vector<S>(2 * size, e()); lz = std::vector<F>(size, id()); for (int i = 0; i < _n; i++) d[size + i] = v[i]; for (int i = size - 1; i >= 1; i--) { update(i); } } void set(int p, S x) { assert(0 <= p && p < _n); p += size; for (int i = log; i >= 1; i--) push(p >> i); d[p] = x; for (int i = 1; i <= log; i++) update(p >> i); } S get(int p) { assert(0 <= p && p < _n); p += size; for (int i = log; i >= 1; i--) push(p >> i); return d[p]; } S prod(int l, int r) { assert(0 <= l && l <= r && r <= _n); if (l == r) return e(); l += size; r += size; for (int i = log; i >= 1; i--) { if (((l >> i) << i) != l) push(l >> i); if (((r >> i) << i) != r) push((r - 1) >> i); } S sml = e(), smr = e(); while (l < r) { if (l & 1) sml = op(sml, d[l++]); if (r & 1) smr = op(d[--r], smr); l >>= 1; r >>= 1; } return op(sml, smr); } S all_prod() { return d[1]; } void apply(int p, F f) { assert(0 <= p && p < _n); p += size; for (int i = log; i >= 1; i--) push(p >> i); d[p] = mapping(f, d[p]); for (int i = 1; i <= log; i++) update(p >> i); } void apply(int l, int r, F f) { assert(0 <= l && l <= r && r <= _n); if (l == r) return; l += size; r += size; for (int i = log; i >= 1; i--) { if (((l >> i) << i) != l) push(l >> i); if (((r >> i) << i) != r) push((r - 1) >> i); } { int l2 = l, r2 = r; while (l < r) { if (l & 1) all_apply(l++, f); if (r & 1) all_apply(--r, f); l >>= 1; r >>= 1; } l = l2; r = r2; } for (int i = 1; i <= log; i++) { if (((l >> i) << i) != l) update(l >> i); if (((r >> i) << i) != r) update((r - 1) >> i); } } template <bool (*g)(S)> int max_right(int l) { return max_right(l, [](S x) { return g(x); }); } template <class G> int max_right(int l, G g) { assert(0 <= l && l <= _n); assert(g(e())); if (l == _n) return _n; l += size; for (int i = log; i >= 1; i--) push(l >> i); S sm = e(); do { while (l % 2 == 0) l >>= 1; if (!g(op(sm, d[l]))) { while (l < size) { push(l); l = (2 * l); if (g(op(sm, d[l]))) { sm = op(sm, d[l]); l++; } } return l - size; } sm = op(sm, d[l]); l++; } while ((l & -l) != l); return _n; } template <bool (*g)(S)> int min_left(int r) { return min_left(r, [](S x) { return g(x); }); } template <class G> int min_left(int r, G g) { assert(0 <= r && r <= _n); assert(g(e())); if (r == 0) return 0; r += size; for (int i = log; i >= 1; i--) push((r - 1) >> i); S sm = e(); do { r--; while (r > 1 && (r % 2)) r >>= 1; if (!g(op(d[r], sm))) { while (r < size) { push(r); r = (2 * r + 1); if (g(op(d[r], sm))) { sm = op(d[r], sm); r--; } } return r + 1 - size; } sm = op(d[r], sm); } while ((r & -r) != r); return 0; } private: int _n, size, log; std::vector<S> d; std::vector<F> lz; void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); } void all_apply(int k, F f) { d[k] = mapping(f, d[k]); if (k < size) lz[k] = composition(f, lz[k]); } void push(int k) { all_apply(2 * k, lz[k]); all_apply(2 * k + 1, lz[k]); lz[k] = id(); } }; } // namespace atcoder using S = int; S op(S a, S b) { return a + b; } S e() { return 0; } using F = int; S mapping(F f, S x) { return f + x; } F composition(F a, F b) { return a + b; } F id() { return 0; } int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); #define int std::int64_t int n; std::cin >> n; std::vector<int> v(n), w(n); for (int i = 0; i < 2 * n; i++) { auto k = i / 2; std::cin >> (i % 2 ? w[k] : v[k]); } // a^4 + 2a^2 + 1 // let t = a^2 => (t + 1)^2 // (t * (t + 2)) % 5 + 1 also // (a^2 + 1)^2 // // 2 3 // 10 11 12 // 17 // // 2 10 17 = 29 // 2 11 17 = 30 // 2 12 17 = 31 // 3 10 17 = 30 // 3 11 17 = 31 // 3 12 17 = 32 /* 4 1 5 2 3 4 6 1 5 17: [n = 4] 18: [v = {1,2,4,1}] 19: [w = {5,3,6,5}] */ // we are going to find the count of every sum basically // after which we can trivially use above formula to find out // the sum // // the length is the length of last block v[n - 1], w[n - 1] // // 1 = 1 // 1 1 = 2 // 1 1 = 2 // 1 = 1 // 1 1 1 1 1 // 2 2 2 2 2 // 2 2 2 2 1 // 1 1 1 1 1 // 1 3 5 6 6 5 3 1 // // x5 // 1 // 2 1 // 2 2 1 // 1 2 2 // 1 2 // 1 // 1 1 1 // 1 1 1 1 // 1 1 1 // 1 // // first step 4 to 6 // 1 1 1 1 1 // 1 1 1 1 1 // 1 1 1 1 1 // = // 1 2 3 3 3 2 1 // // second step 2 to 3 // 1 2 3 3 3 2 1 // 1 2 3 3 3 2 1 // = // 1 3 5 6 6 5 3 1 // // second step 1 to 5 // 1 3 5 6 6 5 3 1 // 1 3 5 6 6 5 3 1 // 1 3 5 6 6 5 3 1 // 1 3 5 6 6 5 3 1 // 1 3 5 6 6 5 3 1 // 1 4 9 15 21 25 21 15 9 4 1 // // ofc the sum starts from the sum of v and ends at sum of w (which is the // index of counter) // // 55: [sum = // {(8,1),(9,4),(10,9),(11,15),(12,21),(13,25),(14,25),(15,21),(16,15),(17,9),(18,4),(19,1)}] // this is correct // // at max 100 steps // // observe that the each value of the vector is controlling only some extra // steps i.e // in this case 5 // second step 1 to 5 // 1 3 5 6 6 5 3 1 // 1 3 5 6 6 5 3 1 // 1 3 5 6 6 5 3 1 // 1 3 5 6 6 5 3 1 // 1 3 5 6 6 5 3 1 // 1 1 1 1 1 // 3 3 3 3 3 // 5 5 5 5 5 // see the 1 idx 0 of the vector acts for len number of elements (0 to 4 // idxs) similarly for 3 idx 1 acts for len number of ele (1 to 5 idxs) // // use lazy segtree n times O(1000 ...) should be possible std::reverse(v.begin(), v.end()); std::reverse(w.begin(), w.end()); auto l = w[0] - v[0] + 1; std::vector<int> a(l, 1); atcoder::lazy_segtree<S, op, e, F, mapping, composition, id> seg(110 * 1110); for (int i = 1; i < n; i++) { l = w[i] - v[i] + 1; for (int j = 0; j < a.size(); j++) { auto k = j + l - 1; seg.apply(j, k + 1, a[j]); } a.resize(a.size() + l - 1); for (int j = 0; j < a.size() + l; j++) { a[j] = seg.get(j); seg.set(j, 0); } } auto vs = std::accumulate(v.begin(), v.end(), 0LL); auto ws = std::accumulate(w.begin(), w.end(), 0LL); std::vector<std::pair<int, int>> vc; for (int i = 0, v = vs; i < a.size(); i++, v++) { vc.push_back({v, a[i]}); } std::int64_t ans = 0; for (auto [v, c] : vc) { auto k = std::pow(v, 2); std::int64_t res = static_cast<std::int64_t>(k) * (k + 2); res %= 5; res++; ans += res * c; } std::cout << ans << "\n"; #undef int return 0; }

Compilation message (stderr)

MODSUM.cpp: In function 'int main()':
MODSUM.cpp:411:27: warning: comparison of integer expressions of different signedness: 'int64_t' {aka 'long int'} and 'std::vector<long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
MODSUM.cpp:417:27: warning: comparison of integer expressions of different signedness: 'int64_t' {aka 'long int'} and 'long unsigned int' [-Wsign-compare]
MODSUM.cpp:427:31: warning: comparison of integer expressions of different signedness: 'int64_t' {aka 'long int'} and 'std::vector<long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
MODSUM.cpp:424:10: warning: unused variable 'ws' [-Wunused-variable]
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...