結果
| 問題 | No.880 Yet Another Segment Tree Problem |
| コンテスト | |
| ユーザー |
risujiroh
|
| 提出日時 | 2020-09-11 17:02:51 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.89.0) |
| 結果 |
AC
|
| 実行時間 | 241 ms / 5,000 ms |
| コード長 | 3,369 bytes |
| 記録 | |
| コンパイル時間 | 15,430 ms |
| コンパイル使用メモリ | 454,736 KB |
| 実行使用メモリ | 7,844 KB |
| 最終ジャッジ日時 | 2025-06-20 10:36:38 |
| 合計ジャッジ時間 | 21,395 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 38 |
ソースコード
#pragma GCC optimize("Ofast")
#pragma GCC target("avx2,bmi,bmi2,lzcnt")
#include <bits/extc++.h>
#include <x86intrin.h>
int64_t binary_gcd(int64_t a, int64_t b) {
a = abs(a), b = abs(b);
if (a == 0) return b;
int k = _tzcnt_u64(a | b);
a >>= _tzcnt_u64(a);
while (b) {
b >>= _tzcnt_u64(b);
if (a > b) std::swap(a, b);
b -= a;
}
return a << k;
}
struct beats {
static constexpr int inf = 0x3f3f3f3f;
struct node {
int mx, lcm = 1;
int64_t sum;
friend node operator*(const node& a, const node& b) {
int lcm = inf;
if (std::max(a.lcm, b.lcm) < inf)
lcm = std::min<int64_t>(a.lcm / binary_gcd(a.lcm, b.lcm) * b.lcm, inf);
return {std::max(a.mx, b.mx), lcm, a.sum + b.sum};
}
};
int sz;
std::vector<node> tree;
beats(int n) {
for (sz = 1; sz < n;) sz *= 2;
tree.resize(2 * sz);
for (int i = 0; i < n; ++i) {
int a;
std::cin >> a;
tree[sz + i] = {a, a, a};
}
for (int i = sz; i-- > 1;) pull(i);
}
void pull(int i) { tree[i] = tree[2 * i] * tree[2 * i + 1]; }
void push(int i, int j, int64_t len) {
if (tree[i].mx * len == tree[i].sum)
tree[j] = {tree[i].mx, tree[i].lcm, tree[i].sum >> 1};
}
void assign(int l, int r, int x, int i, int a, int b) {
if (r <= a or b <= l) return;
if (l <= a and b <= r) {
tree[i].mx = tree[i].lcm = x;
tree[i].sum = tree[i].mx * int64_t(b - a);
return;
}
push(i, 2 * i, b - a), push(i, 2 * i + 1, b - a);
int m = (a + b) >> 1;
assign(l, r, x, 2 * i, a, m), assign(l, r, x, 2 * i + 1, m, b);
pull(i);
}
void assign(int l, int r, int x) { assign(l, r, x, 1, 0, sz); }
void gcd(int l, int r, int x, int i, int a, int b) {
if (r <= a or b <= l or x % tree[i].lcm == 0) return;
if (l <= a and b <= r and tree[i].mx * int64_t(b - a) == tree[i].sum) {
tree[i].mx = tree[i].lcm = binary_gcd(tree[i].mx, x);
tree[i].sum = tree[i].mx * int64_t(b - a);
return;
}
push(i, 2 * i, b - a), push(i, 2 * i + 1, b - a);
int m = (a + b) >> 1;
gcd(l, r, x, 2 * i, a, m), gcd(l, r, x, 2 * i + 1, m, b);
pull(i);
}
void gcd(int l, int r, int x) { gcd(l, r, x, 1, 0, sz); }
int max(int l, int r, int i, int a, int b) {
if (r <= a or b <= l) return 0;
if (l <= a and b <= r) return tree[i].mx;
push(i, 2 * i, b - a), push(i, 2 * i + 1, b - a);
int m = (a + b) >> 1;
return std::max(max(l, r, 2 * i, a, m), max(l, r, 2 * i + 1, m, b));
}
int max(int l, int r) { return max(l, r, 1, 0, sz); }
int64_t sum(int l, int r, int i, int a, int b) {
if (r <= a or b <= l) return 0;
if (l <= a and b <= r) return tree[i].sum;
push(i, 2 * i, b - a), push(i, 2 * i + 1, b - a);
int m = (a + b) >> 1;
return sum(l, r, 2 * i, a, m) + sum(l, r, 2 * i + 1, m, b);
}
int64_t sum(int l, int r) { return sum(l, r, 1, 0, sz); }
};
int main() {
using namespace std;
cin.tie(nullptr)->sync_with_stdio(false);
int n, q;
cin >> n >> q;
beats b(n);
while (q--) {
int t, l, r;
cin >> t >> l >> r;
--l;
if (t == 1) {
int x;
cin >> x;
b.assign(l, r, x);
} else if (t == 2) {
int x;
cin >> x;
b.gcd(l, r, x);
} else if (t == 3) {
cout << b.max(l, r) << '\n';
} else {
cout << b.sum(l, r) << '\n';
}
}
}
risujiroh