結果
| 問題 |
No.880 Yet Another Segment Tree Problem
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2019-09-06 22:52:03 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 1,041 ms / 5,000 ms |
| コード長 | 3,036 bytes |
| コンパイル時間 | 1,892 ms |
| コンパイル使用メモリ | 163,452 KB |
| 実行使用メモリ | 15,032 KB |
| 最終ジャッジ日時 | 2025-06-20 10:26:20 |
| 合計ジャッジ時間 | 15,585 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 38 |
ソースコード
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
#define repr(i, n) for (int i = (n) - 1; i >= 0; i--)
#define range(a) a.begin(), a.end()
using namespace std;
using ll = long long;
constexpr int U = 1 << 17;
ll gcd(ll x, ll y) {
while (y != 0) {
ll r = x % y;
x = y;
y = r;
}
return x;
}
ll lcm(ll x, ll y) {
return x / gcd(x, y) * y;
}
ll dat[U * 2];
ll dat2[U * 2];
ll sum[U * 2];
ll lazy[U * 2];
ll least[U * 2];
ll sz[U * 2];
constexpr ll INF = 1.01e9;
void apply_set(int k, ll x) {
if (x == 0) return;
dat[k] = x;
dat2[k] = x;
sum[k] = x * sz[k];
lazy[k] = x;
least[k] = x;
}
void push(int k) {
apply_set(k * 2 + 0, lazy[k]);
apply_set(k * 2 + 1, lazy[k]);
lazy[k] = 0;
}
void pull(int k) {
dat[k] = max(dat[k * 2], dat[k * 2 + 1]);
dat2[k] = min(dat2[k * 2], dat2[k * 2 + 1]);
sum[k] = sum[k * 2] + sum[k * 2 + 1];
least[k] = min(INF, lcm(least[k * 2], least[k * 2 + 1]));
}
void update_set(int a, int b, ll x, int k = 1, int l = 0, int r = U) {
if (r <= a || b <= l) return;
if (a <= l && r <= b) {
apply_set(k, x);
return;
}
push(k);
int m = l + r >> 1;
update_set(a, b, x, k * 2 + 0, l, m);
update_set(a, b, x, k * 2 + 1, m, r);
pull(k);
}
void update_gcd(int a, int b, ll g, int k = 1, int l = 0, int r = U) {
if (r <= a || b <= l) return;
if (a <= l && r <= b && dat[k] == dat2[k]) {
apply_set(k, gcd(dat[k], g));
return;
}
if (lcm(least[k], g) == g) return;
push(k);
int m = l + r >> 1;
update_gcd(a, b, g, k * 2 + 0, l, m);
update_gcd(a, b, g, k * 2 + 1, m, r);
pull(k);
}
ll query_max(int a, int b, int k = 1, int l = 0, int r = U) {
if (r <= a || b <= l) return -1e18;
if (a <= l && r <= b) return dat[k];
push(k);
int m = l + r >> 1;
ll vl = query_max(a, b, k * 2 + 0, l, m);
ll vr = query_max(a, b, k * 2 + 1, m, r);
return max(vl, vr);
}
ll query_sum(int a, int b, int k = 1, int l = 0, int r = U) {
if (r <= a || b <= l) return 0;
if (a <= l && r <= b) return sum[k];
push(k);
int m = l + r >> 1;
ll vl = query_sum(a, b, k * 2 + 0, l, m);
ll vr = query_sum(a, b, k * 2 + 1, m, r);
return vl + vr;
}
int main() {
cin.tie(nullptr);
ios::sync_with_stdio(false);
int N, Q; cin >> N >> Q;
vector<int> A(N);
rep(i, U * 2) {
least[i] = 1;
dat[i] = -1e18;
dat2[i] = 1e18;
}
rep(i, N) {
cin >> A[i];
dat[i + U] = A[i];
dat2[i + U] = A[i];
sum[i + U] = A[i];
least[i + U] = A[i];
sz[i + U] = 1;
}
for (int i = U - 1; i >= 1; i--) pull(i), sz[i] = sz[i * 2] + sz[i * 2 + 1];
while (Q--) {
int type; cin >> type;
if (type == 1) {
int l, r, x; cin >> l >> r >> x; l--;
update_set(l, r, x);
} else if (type == 2) {
int l, r, x; cin >> l >> r >> x; l--;
update_gcd(l, r, x);
} else if (type == 3) {
int l, r; cin >> l >> r; l--;
cout << query_max(l, r) << '\n';
} else {
int l, r; cin >> l >> r; l--;
cout << query_sum(l, r) << '\n';
}
}
}