結果
| 問題 |
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;
}
}
}