結果
問題 |
No.880 Yet Another Segment Tree Problem
|
ユーザー |
|
提出日時 | 2025-10-06 18:21:27 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 4,592 bytes |
コンパイル時間 | 1,485 ms |
コンパイル使用メモリ | 138,036 KB |
実行使用メモリ | 115,184 KB |
最終ジャッジ日時 | 2025-10-06 18:21:55 |
合計ジャッジ時間 | 26,449 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 33 TLE * 1 -- * 4 |
ソースコード
#include <iostream> #include <vector> #include <map> #include <unordered_map> #include <utility> #include <atcoder/lazysegtree> // #include <kotone/container_hash> // https://github.com/amiast/cpp-utility #ifndef KOTONE_CONTAINER_HASH_HPP #define KOTONE_CONTAINER_HASH_HPP 1 #include <cstdint> #include <vector> #include <array> #include <utility> namespace kotone { // A hash for pairs of integral values. // If possible, consider hashing plain integers as a computationally-cheaper alternative. template <typename S, typename T> struct pair_hash { std::size_t operator()(const std::pair<S, T> &p) const { uint64_t x = static_cast<uint64_t>(p.first); uint64_t y = static_cast<uint64_t>(p.second); return std::hash<uint64_t>()((x >> 32 ^ x) << 32 | (y >> 32 ^ y)); } }; } // namespace kotone #endif // KOTONE_CONTAINER_HASH_HPP struct S { int64_t sum = 0, max = 0; int count = 0; }; S op(S a, S b) { return {a.sum + b.sum, a.max > b.max ? a.max : b.max, a.count + b.count}; } S e() { return {}; } S mapping(int64_t f, S x) { if (f < 0) return x; return {f * x.count, f, x.count}; } int64_t composition(int64_t f, int64_t g) { if (f < 0) return g; return f; } int64_t id() { return -1; } int main() { int N, Q; std::cin >> N >> Q; std::vector<S> A(N); for (S &a : A) std::cin >> a.sum, a.max = a.sum, a.count = 1; atcoder::lazy_segtree<S, op, e, int64_t, mapping, composition, id> seg(A); std::map<int, std::pair<int, int64_t>> intervals; int i = 0; while (i < N) { int j = i + 1; if (A[i].sum > 1) { while (j < N && A[i].sum == A[j].sum) j++; intervals[i] = {j, A[i].sum}; } i = j; } std::unordered_map<std::pair<int64_t, int64_t>, int64_t, kotone::pair_hash<int64_t, int64_t>> gcd_map; auto gcd = [&](auto gcd, int64_t a, int64_t b) -> int64_t { if (a < b) return gcd(gcd, b, a); auto iter = gcd_map.find({a, b}); if (b == 0) return a; if (iter != gcd_map.end()) return iter->second; return gcd_map[{a, b}] = gcd(gcd, b, a % b); }; while (Q--) { int t, l, r; std::cin >> t >> l >> r; l--; if (t == 1) { int64_t y; std::cin >> y; seg.apply(l, r, y); auto start = intervals.lower_bound(l); if (start != intervals.begin() && l < std::prev(start)->second.first) { if (std::prev(start)->second.first > r) { start = intervals.emplace(r, std::prev(start)->second).first; } std::prev(start)->second.first = l; } auto stop = intervals.lower_bound(r); if (stop != intervals.begin() && r < std::prev(stop)->second.first) { stop = intervals.emplace(r, std::prev(stop)->second).first; } intervals.erase(start, stop); intervals[l] = {r, y}; } else if (t == 2) { int64_t x; std::cin >> x; auto start = intervals.lower_bound(l); if (start != intervals.begin() && l < std::prev(start)->second.first) { if (std::prev(start)->second.first > r) { start = intervals.emplace(r, std::prev(start)->second).first; } start = intervals.emplace(l, std::prev(start)->second).first; std::prev(start)->second.first = l; } auto stop = intervals.lower_bound(r); if (stop != intervals.begin() && r < std::prev(stop)->second.first) { stop = intervals.emplace(r, std::prev(stop)->second).first; std::prev(stop)->second.first = r; } auto iter = start; while (iter != stop) { int nl = iter->first; auto &[nr, val] = iter->second; val = gcd(gcd, val, x); seg.apply(nl, nr, val); if (val > 1) { if (iter != intervals.begin() && nl == std::prev(iter)->second.first && val == std::prev(iter)->second.second) { std::prev(iter)->second.first = nr; iter = intervals.erase(iter); } else iter++; } else iter = intervals.erase(iter); } } else if (t == 3) { std::cout << seg.prod(l, r).max << std::endl; } else { std::cout << seg.prod(l, r).sum << std::endl; } } }