結果
| 問題 |
No.3265 地元に帰れば天才扱い!
|
| コンテスト | |
| ユーザー |
urectanc
|
| 提出日時 | 2025-09-06 14:50:33 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
AC
|
| 実行時間 | 521 ms / 2,500 ms |
| コード長 | 10,887 bytes |
| コンパイル時間 | 19,249 ms |
| コンパイル使用メモリ | 384,512 KB |
| 実行使用メモリ | 30,624 KB |
| 最終ジャッジ日時 | 2025-09-06 14:51:14 |
| 合計ジャッジ時間 | 32,573 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 4 |
| other | AC * 21 |
ソースコード
use bit::BinaryIndexedTree;
use lazy_segtree::{LazySegmentTree, Operator};
use proconio::{input, marker::Usize1};
use std::io::Write;
fn main() {
input! {
n: usize, m: usize,
mut alr: [(i64, Usize1, usize); n],
q: usize,
queries: [(Usize1, Usize1, Usize1, usize); q],
}
let mut stdout = std::io::BufWriter::new(std::io::stdout().lock());
let mut pos = (0..n).collect::<Vec<_>>();
let mut bit_sum = BinaryIndexedTree::new(m, 0);
let mut init = vec![0; m + 1];
for (i, &(a, l, r)) in alr.iter().enumerate() {
bit_sum.add(i, a);
init[l] += 1;
init[r] -= 1;
}
for i in 0..m {
init[i + 1] += init[i];
}
let mut seg_cover = LazySegmentTree::<O>::from(init);
let mut score = 0;
for &(a, l, r) in &alr {
let sum = bit_sum.sum(l, r);
score += a * (r - l) as i64 - sum;
}
for &(x, to, u, v) in &queries {
let (a, l, r) = alr[x];
let from = pos[x];
pos[x] = to;
score -= a * (r - l) as i64;
alr[x] = (a, u, v);
score += a * (v - u) as i64;
let sum = bit_sum.sum(l, r);
score += sum;
bit_sum.add(from, -a);
bit_sum.add(to, a);
let sum = bit_sum.sum(u, v);
score -= sum;
seg_cover.apply_range(l, r, -1);
let cover = seg_cover.get(from);
score += cover * a;
let cover = seg_cover.get(to);
score -= cover * a;
seg_cover.apply_range(u, v, 1);
writeln!(stdout, "{score}").unwrap();
}
}
struct O;
impl Operator for O {
type Value = i64;
type Map = i64;
fn identity() -> Self::Value {
0
}
fn identity_map() -> Self::Map {
0
}
fn op(_a: &Self::Value, _b: &Self::Value) -> Self::Value {
0
}
fn apply(f: &Self::Map, x: &Self::Value) -> Self::Value {
*x + *f
}
fn compose(f: &Self::Map, g: &Self::Map) -> Self::Map {
*f + *g
}
}
#[allow(dead_code)]
mod bit {
pub struct BinaryIndexedTree<T> {
n: usize,
array: Vec<T>,
e: T,
}
impl<T> BinaryIndexedTree<T>
where
T: Clone + std::ops::AddAssign + std::ops::Sub<Output = T> + std::cmp::PartialOrd,
{
pub fn new(n: usize, e: T) -> Self {
Self {
n,
array: vec![e.clone(); n + 1],
e,
}
}
pub fn add(&mut self, i: usize, x: T) {
let mut i = i + 1;
while i <= self.n {
self.array[i] += x.clone();
i += i & i.wrapping_neg();
}
}
pub fn cum(&self, mut i: usize) -> T {
let mut cum = self.e.clone();
while i > 0 {
cum += self.array[i].clone();
i -= i & i.wrapping_neg();
}
cum
}
pub fn sum(&self, l: usize, r: usize) -> T {
self.cum(r) - self.cum(l)
}
pub fn lower_bound(&self, mut x: T) -> usize {
let mut i = 0;
let mut k = 1 << (self.n.next_power_of_two().trailing_zeros());
while k > 0 {
if i + k <= self.n && self.array[i + k] < x {
x = x - self.array[i + k].clone();
i += k;
}
k >>= 1;
}
i
}
}
}
#[allow(dead_code)]
mod lazy_segtree {
pub trait Operator {
type Value: Clone;
type Map: Clone;
fn identity() -> Self::Value;
fn identity_map() -> Self::Map;
fn op(a: &Self::Value, b: &Self::Value) -> Self::Value;
fn apply(f: &Self::Map, x: &Self::Value) -> Self::Value;
fn compose(f: &Self::Map, g: &Self::Map) -> Self::Map;
}
pub struct LazySegmentTree<O: Operator> {
n: usize,
offset: usize,
height: usize,
value: Vec<O::Value>,
map: Vec<O::Map>,
}
impl<O: Operator> From<Vec<O::Value>> for LazySegmentTree<O> {
fn from(v: Vec<O::Value>) -> Self {
let n = v.len();
let offset = n.next_power_of_two();
let height = offset.trailing_zeros() as usize;
let mut value = vec![O::identity(); 2 * offset];
value[offset..][..n].clone_from_slice(&v);
let map = vec![O::identity_map(); offset];
let mut ret = Self {
n,
offset,
height,
value,
map,
};
for i in (1..offset).rev() {
ret.update(i);
}
ret
}
}
impl<O: Operator> LazySegmentTree<O> {
pub fn new(n: usize) -> Self {
vec![O::identity(); n].into()
}
pub fn as_slice(&mut self) -> &[O::Value] {
for i in 1..self.offset {
self.push(i);
}
&self.value[self.offset..][..self.n]
}
pub fn get(&mut self, i: usize) -> O::Value {
debug_assert!(i < self.n);
let i = i + self.offset;
for k in (1..=self.height).rev() {
self.push(i >> k);
}
self.value[i].clone()
}
pub fn set(&mut self, i: usize, x: O::Value) {
debug_assert!(i < self.n);
let i = i + self.offset;
for k in (1..=self.height).rev() {
self.push(i >> k);
}
self.value[i] = x;
for k in 1..=self.height {
self.update(i >> k);
}
}
pub fn prod(&mut self, l: usize, r: usize) -> O::Value {
debug_assert!(l <= r && r <= self.n);
let (mut l, mut r) = (l + self.offset, r + self.offset);
for k in (1..=self.height).rev() {
if ((l >> k) << k) != l {
self.push(l >> k);
}
if ((r >> k) << k) != r {
self.push(r >> k);
}
}
let mut prod_l = O::identity();
let mut prod_r = O::identity();
while l < r {
if l & 1 == 1 {
prod_l = O::op(&prod_l, &self.value[l]);
l += 1;
}
if r & 1 == 1 {
prod_r = O::op(&self.value[r - 1], &prod_r);
}
l >>= 1;
r >>= 1;
}
O::op(&prod_l, &prod_r)
}
pub fn all_prod(&self) -> O::Value {
self.value[1].clone()
}
pub fn apply(&mut self, i: usize, f: O::Map) {
debug_assert!(i < self.n);
let i = i + self.offset;
for k in (1..=self.height).rev() {
self.push(i >> k);
}
self.value[i] = O::apply(&f, &self.value[i]);
for k in 1..=self.height {
self.update(i >> k);
}
}
pub fn apply_range(&mut self, l: usize, r: usize, f: O::Map) {
debug_assert!(l <= r && r <= self.n);
let (l, r) = (l + self.offset, r + self.offset);
for k in (1..=self.height).rev() {
if ((l >> k) << k) != l {
self.push(l >> k);
}
if ((r >> k) << k) != r {
self.push(r >> k);
}
}
{
let (mut l, mut r) = (l, r);
while l < r {
if l & 1 == 1 {
self.all_apply(l, &f);
l += 1;
}
if r & 1 == 1 {
self.all_apply(r - 1, &f);
}
l >>= 1;
r >>= 1;
}
}
for k in 1..=self.height {
if ((l >> k) << k) != l {
self.update(l >> k);
}
if ((r >> k) << k) != r {
self.update(r >> k);
}
}
}
pub fn max_right(&mut self, l: usize, f: impl Fn(&O::Value) -> bool) -> usize {
debug_assert!(l <= self.n);
debug_assert!(f(&O::identity()));
let mut i = l + self.offset;
for k in (1..=self.height).rev() {
self.push(i >> k);
}
let mut prod = O::identity();
loop {
i >>= i.trailing_zeros();
let next = O::op(&prod, &self.value[i]);
if !f(&next) {
break;
}
i += 1;
prod = next;
if i & i.wrapping_neg() == i {
return self.n;
}
}
while i < self.offset {
self.push(i);
i *= 2;
let next = O::op(&prod, &self.value[i]);
if f(&next) {
i += 1;
prod = next;
}
}
i - self.offset
}
pub fn min_left(&mut self, r: usize, f: impl Fn(&O::Value) -> bool) -> usize {
debug_assert!(r <= self.n);
debug_assert!(f(&O::identity()));
let mut i = r + self.offset;
for k in (1..=self.height).rev() {
self.push((i - 1) >> k);
}
let mut prod = O::identity();
loop {
i >>= i.trailing_zeros();
if i > 1 {
i -= 1;
}
let next = O::op(&self.value[i], &prod);
if !f(&next) {
break;
}
prod = next;
if i & i.wrapping_neg() == i {
return 0;
}
}
while i < self.offset {
self.push(i);
i = 2 * i + 1;
let next = O::op(&self.value[i], &prod);
if f(&next) {
i -= 1;
prod = next;
}
}
i + 1 - self.offset
}
fn update(&mut self, i: usize) {
self.value[i] = O::op(&self.value[2 * i], &self.value[2 * i + 1]);
}
fn all_apply(&mut self, i: usize, f: &O::Map) {
self.value[i] = O::apply(f, &self.value[i]);
if i < self.offset {
self.map[i] = O::compose(f, &self.map[i]);
}
}
fn push(&mut self, i: usize) {
let f = std::mem::replace(&mut self.map[i], O::identity_map());
self.all_apply(2 * i, &f);
self.all_apply(2 * i + 1, &f);
}
}
}
urectanc