#line 1 "test/yukicoder/880.test.cpp" #define PROBLEM "https://yukicoder.me/problems/no/880" #line 2 "template.hpp" // #pragma GCC target("avx2") // #pragma GCC optimize("O3") // #pragma GCC optimize("unroll-loops") #include using namespace std; // https://xn--kst.jp/blog/2019/08/29/cpp-comp/ // debug methods // usage: debug(x,y); // vector 出力できるように修正 template ostream& debug_print(ostream& os, const vector& v) { os << "["; for (size_t i = 0; i < v.size(); ++i) { os << v[i]; if (i < v.size() - 1) os << ", "; } os << "]"; return os; } template ostream& debug_print(ostream& os, const T& var) { os << var; return os; } #define CHOOSE(a) CHOOSE2 a #define CHOOSE2(a0, a1, a2, a3, a4, x, ...) x #define debug_1(x1) { cout << #x1 << ": "; debug_print(cout, x1) << endl; } #define debug_2(x1, x2) { cout << #x1 << ": "; debug_print(cout, x1) << ", " << #x2 << ": "; debug_print(cout, x2) << endl; } #define debug_3(x1, x2, x3) { cout << #x1 << ": "; debug_print(cout, x1) << ", " << #x2 << ": "; debug_print(cout, x2) << ", " << #x3 << ": "; debug_print(cout, x3) << endl; } #define debug_4(x1, x2, x3, x4) { cout << #x1 << ": "; debug_print(cout, x1) << ", " << #x2 << ": "; debug_print(cout, x2) << ", " << #x3 << ": "; debug_print(cout, x3) << ", " << #x4 << ": "; debug_print(cout, x4) << endl; } #define debug_5(x1, x2, x3, x4, x5) { cout << #x1 << ": "; debug_print(cout, x1) << ", " << #x2 << ": "; debug_print(cout, x2) << ", " << #x3 << ": "; debug_print(cout, x3) << ", " << #x4 << ": "; debug_print(cout, x4) << ", " << #x5 << ": "; debug_print(cout, x5) << endl; } #ifdef LOCAL #define debug(...) CHOOSE((__VA_ARGS__, debug_5, debug_4, debug_3, debug_2, debug_1, ~))(__VA_ARGS__) #else #define debug(...) #endif using ll = long long; using vl = vector; using Graph = vector>; using P = pair; #define all(v) v.begin(), v.end() template inline bool chmax(T &a, T b) { return ((a < b) ? (a = b, true) : (false)); } template inline bool chmin(T &a, T b) { return ((a > b) ? (a = b, true) : (false)); } #define rep1(i, n) for(ll i = 1; i <= ((ll)n); ++i) // https://trap.jp/post/1224/ template constexpr auto min(T... a) { return min(initializer_list>{a...}); } template constexpr auto max(T... a) { return max(initializer_list>{a...}); } template void input(T &...a) { (cin >> ... >> a); } template void input(vector &a) { for(T &x : a) cin >> x; } void print() { cout << '\n'; } template void print(const T &a, const Ts &...b) { cout << a; (cout << ... << (cout << ' ', b)); cout << '\n'; } void print(const string &s) { cout << s << '\n'; } template struct is_container : std::false_type {}; template struct is_container().begin()), decltype(std::declval().end())>> : std::true_type {}; template typename enable_if::value>::type print(const Container& x) { if (!x.empty()) { auto it = x.begin(); for (; it != prev(x.end()); ++it) { cout << *it << " "; } cout << *it << "\n"; // 最後の要素を出力して改行 } } #define INT(...) \ int __VA_ARGS__; \ input(__VA_ARGS__) #define LL(...) \ long long __VA_ARGS__; \ input(__VA_ARGS__) #define STR(...) \ string __VA_ARGS__; \ input(__VA_ARGS__) #define REP1(a) for(ll i = 0; i < a; i++) #define REP2(i, a) for(ll i = 0; i < a; i++) #define REP3(i, a, b) for(ll i = a; i < b; i++) #define REP4(i, a, b, c) for(ll i = a; i < b; i += c) #define overload4(a, b, c, d, e, ...) e #define rep(...) overload4(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__) ll inf = 3e18; vl dx = {1, -1, 0, 0}; vl dy = {0, 0, 1, -1}; #line 2 "data_structure/segtree-beats.hpp" // https://rsm9.hatenablog.com/entry/2021/02/01/220408 template // composition(f,g)(x) = f∘g(x) = f(g(x)) // aclと同じ、maspyさん記事と逆 struct segtree_beats { vector v; vector vf; ll n; segtree_beats(ll n) : n(n), v(vector(2 * n, e())), vf(vector(2 * n, id())) {}; segtree_beats(vector v_) : n(v_.size()) { vf = vector(2 * n, id()); v = vector(2 * n, e()); rep(i, n) { v[i + n] = v_[i]; } for(ll i = n - 1; i > 0; i--) { v[i] = op(v[i << 1], v[i << 1 | 1]); } } void apply(ll l, ll r, F f) { l += n; r += n; ll l0 = l / (l & -l); ll r0 = r / (r & -r) - 1; propagate_above(l0); propagate_above(r0); while(l < r) { if(l & 1) { apply_at(l, f); l++; } if(r & 1) { r--; apply_at(r, f); } l >>= 1; r >>= 1; } recul_above(l0); recul_above(r0); } S get(ll x) { x += n; ll maxi = bit_length(x) - 1; for(ll i = maxi; i > 0; i--) { propagate_at(x >> i); } return v[x]; } void set(ll x, S s) { x += n; propagate_above(x); v[x] = s; recul_above(x); } S prod(ll l, ll r) { l += n; r += n; ll l0 = l / (l & -l); ll r0 = r / (r & -r) - 1; propagate_above(l0); propagate_above(r0); S sl = e(), sr = e(); while(l < r) { if(l & 1) { sl = op(sl, v[l]); l++; } if(r & 1) { r--; sr = op(v[r], sr); } l >>= 1; r >>= 1; } return op(sl, sr); } private: void apply_at(ll x, F f) { v[x] = mapping(f, v[x]); if(x < n) { vf[x] = composition(f, vf[x]); // Added for Segment Tree Beats implementation. if(v[x].fail) { propagate_at(x); v[x] = op(v[x << 1], v[x << 1 | 1]); debug(x,v[x].maxi,v[x<<1].maxi,v[x<<1|1].maxi); } } } void propagate_at(ll x) { apply_at(x << 1, vf[x]); apply_at(x << 1 | 1, vf[x]); vf[x] = id(); } ll bit_length(unsigned long long x) { return 64 - countl_zero(x); } void propagate_above(ll x) { ll maxi = bit_length(x) - 1; for(ll i = maxi; i > 0; i--) { propagate_at(x >> i); } return; } void recul_above(ll x) { while(x > 1) { x >>= 1; v[x] = op(v[x << 1], v[x << 1 | 1]); } } }; #line 4 "test/yukicoder/880.test.cpp" struct S { ll mini, maxi, gcd, lcm, num, sum; bool fail; S(ll a, ll num_ = 1) : mini(a), maxi(a), gcd(a), lcm(a), num(num_), sum(a * num_), fail(false) {}; S() = default; }; S e() { S res(0); res.num = 0; return res; } S op(S a, S b) { S res; res.mini = min(a.mini, b.mini); res.maxi = max(a.maxi, b.maxi); res.gcd = gcd(a.gcd, b.gcd); res.lcm = lcm(a.lcm, b.lcm); if(a.lcm == inf or b.lcm == inf or __int128_t(a.lcm) * b.lcm / (1 + gcd(a.lcm, b.lcm)) >= inf) res.lcm = inf; res.num = a.num + b.num; res.sum = a.sum + b.sum; res.fail = a.fail or b.fail; return res; } struct F { // gcdやってassign bool gcd_q, assing_q; ll g, x; }; S mapping(F f, S s) { if(f.assing_q) { s.mini = s.maxi = s.lcm = f.x; s.sum = f.x * s.num; return s; } if(f.gcd_q) { // if(f.g == gcd(s.lcm, f.g)) { // return s; // } if(s.mini == s.maxi) { ll val = gcd(s.mini, f.g); S res(val, s.num); res.fail = s.fail; return res; } debug(s.mini,s.maxi,s.lcm,f.g,"fail occar"); s.fail = true; return s; } return s; } F id() { return F(false, false, 0, 0); } F composition(F f1, F f2) { if(f1.assing_q or (!f2.assing_q and !f2.gcd_q)) { return f1; } if(!f1.gcd_q) { return f2; } if(f2.assing_q) { F res = id(); res.assing_q = true; res.gcd_q = false; res.x = gcd(f1.g, f2.x); return res; } f1.g = gcd(f1.g, f2.g); return f1; } void solve() { LL(n, q); segtree_beats seg(n); rep(i, n) { LL(a); seg.set(i, S(a)); } while(q--) { LL(flag); LL(l, r); l--; if(flag == 1) { LL(x); seg.apply(l, r, F(false, true, 0, x)); } else if(flag == 2) { LL(x); seg.apply(l, r, F(true, false, x, 0)); } else if(flag == 3) { print(seg.prod(l, r).maxi); } else { print(seg.prod(l, r).sum); } // rep(i, n) { cout << seg.get(i).sum << " "; } // print(); // rep(i, n) { cout << seg.v[i].maxi << " "; } // print("max"); // rep(i, n, 2 * n) { cout << seg.v[i].maxi << " "; } // print("max"); // rep(i,2*n){cout<