Submission #16577269
Source Code Expand
#![allow(unused_imports, unused_macros, dead_code)]
macro_rules! trace {
($x:expr) => {
#[cfg(debug_assertions)]
eprintln!(">>> {} = {:?}", stringify!($x), $x)
};
($($xs:expr),*) => { trace!(($($xs),*)) }
}
macro_rules! put {
(.. $x:expr) => {{
let mut it = $x.iter();
if let Some(x) = it.next() { print!("{}", x); }
for x in it { print!(" {}", x); }
println!("");
}};
($x:expr) => { println!("{}", $x) };
($x:expr, $($xs:expr),*) => { print!("{} ", $x); put!($($xs),*) }
}
#[derive(Debug, Clone, Copy)]
struct D {
zero: usize,
one: usize,
inversion: usize,
proportion: usize, // flip したときの転倒数
}
impl D {
fn from(x: &usize) -> Self {
let mut d = D {
zero: 0,
one: 0,
inversion: 0,
proportion: 0,
};
if *x == 0 {
d.zero += 1;
} else {
d.one += 1;
}
d
}
}
impl std::ops::Mul for D {
type Output = D;
fn mul(self, other: D) -> D {
D {
zero: self.zero + other.zero,
one: self.one + other.one,
inversion: self.inversion + other.inversion + self.one * other.zero,
proportion: self.proportion + other.proportion + self.zero * other.one,
}
}
}
impl Monoid for D {
fn unit() -> D {
D {
zero: 0,
one: 0,
inversion: 0,
proportion: 0,
}
}
}
#[derive(Debug, Clone, Copy)]
struct Flip(bool);
impl std::ops::Mul for Flip {
type Output = Flip;
fn mul(self, other: Flip) -> Flip {
Flip(self.0 ^ other.0)
}
}
impl Monoid for Flip {
fn unit() -> Flip {
Flip(false)
}
}
impl Act<D> for Flip {
fn act(&self, d: D) -> D {
if self.0 {
D {
zero: d.one,
one: d.zero,
inversion: d.proportion,
proportion: d.inversion,
}
} else {
d.clone()
}
}
}
fn main() {
let mut sc = Scanner::new();
let n: usize = sc.cin();
let q: usize = sc.cin();
let xs: Vec<usize> = sc.vec(n);
let mut st = LazySegmentTree::from(xs.iter().map(D::from).collect());
for _ in 0..q {
let t: usize = sc.cin();
let left = sc.cin::<usize>() - 1;
let right = sc.cin::<usize>();
if t == 1 {
st.update(left..right, Flip(true));
} else {
let d = st.product(left..right);
put!(d.inversion);
}
}
}
// @seq.lazy_segment_tree.rs
// @algebra.monoid.rs
trait Monoid: std::ops::Mul<Output = Self> + Clone + Copy {
fn unit() -> Self;
}
impl Monoid for i64 {
fn unit() -> Self {
0
}
}
impl Monoid for f64 {
fn unit() -> Self {
0.0
}
}
// @algebra.act.rs
trait Act<X> {
fn act(&self, x: X) -> X;
}
#[derive(Clone)]
struct LazySegmentTree<X, M> {
length: usize, // of leaves
length_upper: usize, // power of 2
size: usize, // of nodes
data: Vec<X>,
act: Vec<M>,
}
impl<X: Monoid, M: Monoid + Act<X>> LazySegmentTree<X, M> {
fn new(length: usize) -> Self {
let mut length_upper = 1;
loop {
if length_upper >= length {
break;
}
length_upper *= 2;
}
let size = length_upper * 2 - 1;
let data = vec![X::unit(); size];
let act = vec![M::unit(); size];
LazySegmentTree {
length,
length_upper,
size,
data,
act,
}
}
fn from(xs: Vec<X>) -> Self {
let mut tree = Self::new(xs.len());
for i in 0..xs.len() {
tree.data[tree.size / 2 + i] = xs[i];
}
for i in (0..tree.size / 2).rev() {
tree.data[i] = tree.data[2 * i + 1] * tree.data[2 * i + 2];
}
tree
}
fn propagation(&mut self, idx: usize) {
if idx < self.size / 2 {
self.act[idx * 2 + 1] = self.act[idx * 2 + 1] * self.act[idx];
self.act[idx * 2 + 2] = self.act[idx * 2 + 2] * self.act[idx];
}
self.data[idx] = self.act[idx].act(self.data[idx]);
self.act[idx] = M::unit();
}
fn update_sub(
&mut self,
range: std::ops::Range<usize>,
m: M,
idx: usize,
focus: std::ops::Range<usize>,
) {
self.propagation(idx);
if focus.end <= range.start || range.end <= focus.start {
return;
}
if range.start <= focus.start && focus.end <= range.end {
self.act[idx] = self.act[idx] * m;
self.propagation(idx);
} else if idx < self.data.len() / 2 {
let mid = (focus.start + focus.end) / 2;
self.update_sub(range.clone(), m, idx * 2 + 1, focus.start..mid);
self.update_sub(range.clone(), m, idx * 2 + 2, mid..focus.end);
self.data[idx] = self.data[idx * 2 + 1] * self.data[idx * 2 + 2];
}
}
fn update(&mut self, range: std::ops::Range<usize>, m: M) {
self.update_sub(range, m, 0, 0..self.length_upper);
}
fn product_sub(
&mut self,
range: std::ops::Range<usize>,
idx: usize,
focus: std::ops::Range<usize>,
) -> X {
self.propagation(idx);
if focus.end <= range.start || range.end <= focus.start {
X::unit()
} else if range.start <= focus.start && focus.end <= range.end {
self.data[idx]
} else {
let mid = (focus.start + focus.end) / 2;
let a = self.product_sub(range.clone(), idx * 2 + 1, focus.start..mid);
let b = self.product_sub(range.clone(), idx * 2 + 2, mid..focus.end);
a * b
}
}
fn product(&mut self, range: std::ops::Range<usize>) -> X {
self.product_sub(range, 0, 0..self.length_upper)
}
fn index(&mut self, i: usize) -> X {
self.product(i..i + 1)
}
fn to_vec(&mut self) -> Vec<X> {
(0..self.length).map(|i| self.index(i)).collect()
}
}
impl<X: std::fmt::Debug, M: std::fmt::Debug> LazySegmentTree<X, M> {
fn debug(&self) {
for i in 0..self.size {
if i > 0 && (i + 1).count_ones() == 1 {
eprintln!();
}
eprint!("{:?} / {:?}; ", &self.data[i], &self.act[i]);
}
eprintln!();
}
}
use std::collections::VecDeque;
use std::io::{self, Write};
use std::str::FromStr;
struct Scanner {
stdin: io::Stdin,
buffer: VecDeque<String>,
}
impl Scanner {
fn new() -> Self {
Scanner {
stdin: io::stdin(),
buffer: VecDeque::new(),
}
}
fn cin<T: FromStr>(&mut self) -> T {
while self.buffer.is_empty() {
let mut line = String::new();
let _ = self.stdin.read_line(&mut line);
for w in line.split_whitespace() {
self.buffer.push_back(String::from(w));
}
}
self.buffer.pop_front().unwrap().parse::<T>().ok().unwrap()
}
fn chars(&mut self) -> Vec<char> {
self.cin::<String>().chars().collect()
}
fn vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
(0..n).map(|_| self.cin()).collect()
}
}
Submission Info
| Submission Time |
|
| Task |
L - Lazy Segment Tree |
| User |
cympfh |
| Language |
Rust (1.42.0) |
| Score |
100 |
| Code Size |
7661 Byte |
| Status |
AC |
| Exec Time |
498 ms |
| Memory |
36976 KiB |
Judge Result
| Set Name |
Sample |
All |
| Score / Max Score |
0 / 0 |
100 / 100 |
| Status |
|
|
| Set Name |
Test Cases |
| Sample |
00-sample-01.txt |
| All |
00-sample-01.txt, 01-01.txt, 01-02.txt, 01-03.txt, 01-04.txt, 01-05.txt, 01-06.txt, 01-07.txt, 01-08.txt, 01-09.txt, 01-10.txt, 01-11.txt, 01-12.txt, 01-13.txt, 01-14.txt, 01-15.txt, 01-16.txt, 01-17.txt, 01-18.txt, 01-19.txt, 01-20.txt, 01-21.txt |
| Case Name |
Status |
Exec Time |
Memory |
| 00-sample-01.txt |
AC |
7 ms |
2076 KiB |
| 01-01.txt |
AC |
2 ms |
2004 KiB |
| 01-02.txt |
AC |
378 ms |
33644 KiB |
| 01-03.txt |
AC |
384 ms |
21928 KiB |
| 01-04.txt |
AC |
59 ms |
6116 KiB |
| 01-05.txt |
AC |
112 ms |
6876 KiB |
| 01-06.txt |
AC |
278 ms |
35880 KiB |
| 01-07.txt |
AC |
108 ms |
3800 KiB |
| 01-08.txt |
AC |
261 ms |
31648 KiB |
| 01-09.txt |
AC |
216 ms |
34144 KiB |
| 01-10.txt |
AC |
188 ms |
18020 KiB |
| 01-11.txt |
AC |
78 ms |
18356 KiB |
| 01-12.txt |
AC |
498 ms |
36808 KiB |
| 01-13.txt |
AC |
444 ms |
36904 KiB |
| 01-14.txt |
AC |
478 ms |
36896 KiB |
| 01-15.txt |
AC |
442 ms |
36960 KiB |
| 01-16.txt |
AC |
473 ms |
36976 KiB |
| 01-17.txt |
AC |
443 ms |
36872 KiB |
| 01-18.txt |
AC |
487 ms |
36908 KiB |
| 01-19.txt |
AC |
446 ms |
36936 KiB |
| 01-20.txt |
AC |
476 ms |
36872 KiB |
| 01-21.txt |
AC |
438 ms |
36956 KiB |