結果
| 問題 |
No.3205 Range Pairwise Xor Query
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-07-18 22:46:07 |
| 言語 | Rust (1.83.0 + proconio) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 16,632 bytes |
| コンパイル時間 | 13,279 ms |
| コンパイル使用メモリ | 396,600 KB |
| 実行使用メモリ | 344,244 KB |
| 最終ジャッジ日時 | 2025-07-18 22:46:49 |
| 合計ジャッジ時間 | 38,389 ms |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 15 TLE * 5 |
ソースコード
use proconio::{input, marker::Usize1};
use crate::segment_tree::{Monoid, SegmentTree};
const MAX_NUM_DIGITS: usize = 26;
fn main() {
input! {
(n, q): (usize, usize),
aa: [u32; n],
lr: [(Usize1, usize); q],
}
let mut segment_trees = vec![SegmentTree::<S>::new(n); MAX_NUM_DIGITS];
for (i, &a) in aa.iter().enumerate() {
for exp in 0..MAX_NUM_DIGITS {
let bit = (a >> exp & 1) as usize;
segment_trees[exp].set(
i,
S {
num_zeros: bit ^ 1,
num_ones: bit,
sum_ones: 0,
},
);
}
}
let solve = |l: usize, r: usize| {
(0..MAX_NUM_DIGITS)
.map(|exp| segment_trees[exp].prod(l..r).sum_ones << exp)
.sum::<usize>()
};
let ans = lr
.iter()
.map(|&(l, r)| solve(l, r).to_string())
.collect::<Vec<String>>()
.join("\n");
println!("{}", ans);
}
#[derive(Debug, Clone, Copy)]
struct S {
num_zeros: usize,
num_ones: usize,
sum_ones: usize,
}
impl Monoid for S {
fn id() -> Self {
S {
num_zeros: 0,
num_ones: 0,
sum_ones: 0,
}
}
fn prod(&self, rhs: &Self) -> Self {
Self {
num_zeros: self.num_zeros + rhs.num_zeros,
num_ones: self.num_ones + rhs.num_ones,
sum_ones: self.sum_ones
+ rhs.sum_ones
+ self.num_zeros * rhs.num_ones
+ self.num_ones * rhs.num_zeros,
}
}
}
pub mod segment_tree {
//! Performs the following operations on a number sequence of length `n`
//! consisting of elements of monoid in logarithmic time of `n`.
//! * Updates the specified element
//! * Calculates the product of elements in the specified range.
use std::ops::RangeBounds;
/// Defines the method signature of the monoid.
pub trait Monoid: Clone {
/// The identity element
fn id() -> Self;
/// The binary operation
fn prod(&self, rhs: &Self) -> Self;
}
/// # Examples
///
/// ```
/// # use atcoder8_library::segment_tree::{Monoid, SegmentTree};
/// #
/// #[derive(Debug, Clone, PartialEq)]
/// struct Data(i32);
///
/// impl Monoid for Data {
/// fn id() -> Self {
/// Data(0)
/// }
///
/// fn prod(&self, rhs: &Self) -> Self {
/// Data(self.0.max(rhs.0))
/// }
/// }
///
/// let seq = vec![Data(3), Data(-1), Data(4), Data(1), Data(-5), Data(9)];
/// let segtree = SegmentTree::from(seq);
/// assert_eq!(segtree.prod(1..5), Data(4));
/// ```
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SegmentTree<M>
where
M: Monoid,
{
/// Length of sequence
n: usize,
/// Sequences and intermediate data
data: Vec<M>,
}
impl<M: Monoid> From<Vec<M>> for SegmentTree<M> {
fn from(seq: Vec<M>) -> Self {
let mut segtree = Self::new(seq.len());
for (i, x) in seq.into_iter().enumerate() {
segtree.set(i, x);
}
segtree
}
}
impl<M: Monoid> SegmentTree<M> {
/// Creates a Segment Tree for a sequence of length `n`.
/// All elements of the sequence are initialized with the identity element.
///
/// # Arguments
///
/// * `n` - Length of sequence
///
/// # Examples
///
/// ```
/// # use atcoder8_library::segment_tree::{Monoid, SegmentTree};
/// #
/// #[derive(Debug, Clone, PartialEq)]
/// struct Data(i32);
///
/// impl Monoid for Data {
/// fn id() -> Self {
/// Data(0)
/// }
///
/// fn prod(&self, rhs: &Self) -> Self {
/// Data(self.0.max(rhs.0))
/// }
/// }
///
/// let segtree = SegmentTree::<Data>::new(5);
/// assert_eq!(segtree.get(2), Data(0));
/// ```
pub fn new(n: usize) -> Self {
let mut data_len = 1;
while data_len < n {
data_len *= 2;
}
data_len *= 2;
Self {
n,
data: vec![M::id(); data_len],
}
}
/// Update the `p`-th number in the sequence to `x`.
///
/// # Arguments
///
/// * `p` - Index of the element to update
/// * `x` - Value to assign
///
/// # Examples
///
/// ```
/// # use atcoder8_library::segment_tree::{Monoid, SegmentTree};
/// #
/// #[derive(Debug, Clone, PartialEq)]
/// struct Data(i32);
///
/// impl Monoid for Data {
/// fn id() -> Self {
/// Data(0)
/// }
///
/// fn prod(&self, rhs: &Self) -> Self {
/// Data(self.0.max(rhs.0))
/// }
/// }
///
/// let seq = vec![Data(3), Data(-1), Data(4)];
/// let mut segtree = SegmentTree::from(seq);
///
/// assert_eq!(segtree.get(1), Data(-1));
///
/// segtree.set(1, Data(10));
/// assert_eq!(segtree.get(1), Data(10));
/// ```
pub fn set(&mut self, p: usize, x: M) {
assert!(
p < self.n,
"The specified index {} is outside the range of the sequence; the length of the sequence is {}.",
p,
self.n,
);
let mut p = p + self.data.len() / 2;
self.data[p] = x;
while p != 1 {
p >>= 1;
self.data[p] = self.data[2 * p].prod(&self.data[2 * p + 1]);
}
}
/// Returns the `p`-th element.
///
/// # Arguments
///
/// * `p` - Index of the element to get
///
/// # Examples
///
/// ```
/// # use atcoder8_library::segment_tree::{Monoid, SegmentTree};
/// #
/// #[derive(Debug, Clone, PartialEq)]
/// struct Data(i32);
///
/// impl Monoid for Data {
/// fn id() -> Self {
/// Data(0)
/// }
///
/// fn prod(&self, rhs: &Self) -> Self {
/// Data(self.0.max(rhs.0))
/// }
/// }
///
/// let seq = vec![Data(3), Data(-1), Data(4)];
/// let segtree = SegmentTree::from(seq);
/// assert_eq!(segtree.get(1), Data(-1));
/// ```
pub fn get(&self, p: usize) -> M {
assert!(
p < self.n,
"The specified index {} is outside the range of the sequence; the length of the sequence is {}.",
p,
self.n,
);
self.data[self.data.len() / 2 + p].clone()
}
/// Calculates the product of elements of the sequence in the specified range.
///
/// # Arguments
///
/// * `rng` - Range of the product
///
/// # Examples
///
/// ```
/// # use atcoder8_library::segment_tree::{Monoid, SegmentTree};
/// #
/// #[derive(Debug, Clone, PartialEq)]
/// struct Data(i32);
///
/// impl Monoid for Data {
/// fn id() -> Self {
/// Data(0)
/// }
///
/// fn prod(&self, rhs: &Self) -> Self {
/// Data(self.0.max(rhs.0))
/// }
/// }
///
/// let seq = vec![Data(3), Data(-1), Data(4), Data(1), Data(-5), Data(9)];
/// let segtree = SegmentTree::from(seq);
///
/// assert_eq!(segtree.prod(..), Data(9));
/// assert_eq!(segtree.prod(2..), Data(9));
/// assert_eq!(segtree.prod(..5), Data(4));
/// assert_eq!(segtree.prod(2..5), Data(4));
/// assert_eq!(segtree.prod(2..2), Data(0));
/// ```
pub fn prod<R>(&self, rng: R) -> M
where
R: RangeBounds<usize>,
{
let l = match rng.start_bound() {
std::ops::Bound::Included(&start_bound) => start_bound,
std::ops::Bound::Excluded(&start_bound) => start_bound + 1,
std::ops::Bound::Unbounded => 0,
};
let r = match rng.end_bound() {
std::ops::Bound::Included(&end_bound) => end_bound + 1,
std::ops::Bound::Excluded(&end_bound) => end_bound,
std::ops::Bound::Unbounded => self.n,
};
assert!(l <= r, "The slice index starts at {} but ends at {}", l, r);
assert!(
r <= self.n,
"The specified range {}..{} is outside the range of the sequence; the length of sequence is {}",
l,
r,
self.n,
);
let mut sml = M::id();
let mut smr = M::id();
let mut l = l + self.data.len() / 2;
let mut r = r + self.data.len() / 2;
while l < r {
if l & 1 != 0 {
sml = sml.prod(&self.data[l]);
l += 1;
}
if r & 1 != 0 {
r -= 1;
smr = self.data[r].prod(&smr);
}
l >>= 1;
r >>= 1;
}
sml.prod(&smr)
}
/// Returns the product of all elements of a sequence.
///
/// # Examples
///
/// ```
/// # use atcoder8_library::segment_tree::{Monoid, SegmentTree};
/// #
/// #[derive(Debug, Clone, PartialEq)]
/// struct Data(i32);
///
/// impl Monoid for Data {
/// fn id() -> Self {
/// Data(0)
/// }
///
/// fn prod(&self, rhs: &Self) -> Self {
/// Data(self.0.max(rhs.0))
/// }
/// }
///
/// let seq = vec![Data(3), Data(-1), Data(4), Data(1), Data(-5)];
/// let segtree = SegmentTree::from(seq);
/// assert_eq!(segtree.all_prod(), Data(4));
/// ```
pub fn all_prod(&self) -> M {
self.data[1].clone()
}
/// Performs a binary search on the segment tree.
///
/// Returns one `r` satisfying
/// `f(op(seq[l], seq[l + 1], ... , seq[r - 1])) == true` and
/// `f(op(seq[l], seq[l + 1], ... , seq[r])) == false`.
///
/// If no such `r` exists, returns the maximum index of the sequence plus 1;
/// if the length of the sequence is `n`, then `n` is returned.
///
/// # Arguments
///
/// * `l` - Left boundary of the range of the sequence
/// * `f` - Mapping from any element of a monoid to a bool value
///
/// # Panics
///
/// Panic if any of the following:
/// * The identity element is mapped to `false` by `f`.
/// * The left boundary `l` is outside the range of the sequence.
///
/// # Examples
///
/// ```
/// # use atcoder8_library::segment_tree::{Monoid, SegmentTree};
/// #
/// #[derive(Debug, Clone, PartialEq)]
/// struct Data(usize);
///
/// impl Monoid for Data {
/// fn id() -> Self {
/// Data(0)
/// }
///
/// fn prod(&self, rhs: &Self) -> Self {
/// Data(self.0.max(rhs.0))
/// }
/// }
///
/// let seq = vec![Data(3), Data(1), Data(4), Data(1), Data(5), Data(9)];
/// let segtree = SegmentTree::from(seq);
///
/// assert_eq!(segtree.bs_right_boundary(1, |&Data(x)| x < 1), 1);
/// assert_eq!(segtree.bs_right_boundary(1, |&Data(x)| x < 5), 4);
/// assert_eq!(segtree.bs_right_boundary(1, |&Data(x)| x < 10), 6);
/// ```
pub fn bs_right_boundary<F>(&self, l: usize, f: F) -> usize
where
F: Fn(&M) -> bool,
{
assert!(
f(&M::id()),
"The identity element must be mapped to true by `f`."
);
assert!(
l <= self.n,
"Left boundary {} is outside the range of the sequence; the length of sequence is {}.",
l,
self.n,
);
if l == self.n {
return self.n;
}
let size = self.data.len() / 2;
let mut l = l + size;
let mut sm = M::id();
loop {
while l % 2 == 0 {
l >>= 1;
}
if !f(&sm.prod(&self.data[l])) {
while l < size {
l *= 2;
let res = sm.prod(&self.data[l]);
if f(&res) {
sm = res;
l += 1;
}
}
return l - size;
}
sm = sm.prod(&self.data[l]);
l += 1;
if l & l.wrapping_neg() == l {
break;
}
}
self.n
}
/// Performs a binary search on the segment tree.
///
/// Returns one `l` satisfying
/// `f(op(seq[l], seq[l + 1], ... , seq[r - 1])) == true` and
/// `f(op(seq[l - 1], seq[l + 1], ... , seq[r - 1])) == false`.
///
/// If no such `l` exists, returns `0`.
///
/// # Arguments
///
/// * `r` - Right boundary of the range of the sequence
/// * `f` - Mapping from any element of a monoid to a bool value
///
/// # Panics
///
/// Panic if any of the following:
/// * The identity element is mapped to `false` by `f`.
/// * The right boundary `r` is outside the range of the sequence.
///
/// # Examples
///
/// ```
/// # use atcoder8_library::segment_tree::{Monoid, SegmentTree};
/// #
/// #[derive(Debug, Clone, PartialEq)]
/// struct Data(usize);
///
/// impl Monoid for Data {
/// fn id() -> Self {
/// Data(0)
/// }
///
/// fn prod(&self, rhs: &Self) -> Self {
/// Data(self.0.max(rhs.0))
/// }
/// }
///
/// let seq = vec![Data(3), Data(1), Data(4), Data(1), Data(5), Data(9)];
/// let segtree = SegmentTree::from(seq);
///
/// assert_eq!(segtree.bs_left_boundary(4, |&Data(x)| x < 1), 4);
/// assert_eq!(segtree.bs_left_boundary(4, |&Data(x)| x < 3), 3);
/// assert_eq!(segtree.bs_left_boundary(4, |&Data(x)| x < 5), 0);
/// ```
pub fn bs_left_boundary<F>(&self, r: usize, f: F) -> usize
where
F: Fn(&M) -> bool,
{
assert!(
f(&M::id()),
"The identity element must be mapped to true by `f`."
);
assert!(
r <= self.n,
"Right boundary {} is outside the range of the sequence; the length of sequence is {}.",
r,
self.n,
);
if r == 0 {
return 0;
}
let size = self.data.len() / 2;
let mut r = r + size;
let mut sm = M::id();
loop {
r -= 1;
while r > 1 && r % 2 == 1 {
r >>= 1;
}
if !f(&self.data[r].prod(&sm)) {
while r < size {
r = 2 * r + 1;
let res = self.data[r].prod(&sm);
if f(&res) {
sm = res;
r -= 1;
}
}
return r + 1 - size;
}
sm = self.data[r].prod(&sm);
if r & r.wrapping_neg() == r {
break;
}
}
0
}
}
}