Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 218b095

Browse files
committed
ArcSpec::apply() takes a size parameter for convenience
1 parent 468c0b0 commit 218b095

File tree

5 files changed

+48
-40
lines changed

5 files changed

+48
-40
lines changed

‎src/range_query/dynamic_arq.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ impl<T: ArqSpec> Default for DynamicArqNode<T> {
3131

3232
impl<T: ArqSpec> DynamicArqNode<T> {
3333
fn apply(&mut self, f: &T::F, size: i64) {
34-
self.val = T::apply(f, &self.val);
34+
self.val = T::apply(f, &self.val, size);
3535
if size > 1 {
3636
let h = match self.app {
3737
Some(ref g) => T::compose(f, g),
@@ -107,7 +107,7 @@ impl<T: ArqSpec> DynamicArq<T> {
107107
((lp, ls), (rp, s - ls))
108108
}
109109

110-
fn pull(&mut self, p: usize) {
110+
pubfn pull(&mut self, p: usize) {
111111
let (lp, rp) = self.nodes[p].down;
112112
let left_val = &self.nodes[lp].val;
113113
let right_val = &self.nodes[rp].val;

‎src/range_query/mod.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,29 +69,29 @@ mod test {
6969

7070
#[test]
7171
fn test_range_sum() {
72-
let mut arq = StaticArq::<AssignSum>::new(&[(0,1); 10]);
72+
let mut arq = StaticArq::<AssignSum>::new(&[0; 10]);
7373

74-
assert_eq!(arq.query(0, 9), (0,10));
74+
assert_eq!(arq.query(0, 9), 0);
7575

7676
arq.update(1, 3, &10);
7777
arq.update(3, 5, &1);
7878

79-
assert_eq!(arq.query(0, 9), (23,10));
80-
assert_eq!(arq.query(10, 4), (0,0));
79+
assert_eq!(arq.query(0, 9), 23);
80+
assert_eq!(arq.query(10, 4), 0);
8181
}
8282

8383
#[test]
8484
fn test_dynamic_range_sum() {
8585
let mut arq = DynamicArq::<AssignSum>::new(false);
86-
let view = arq.build_from_slice(&[(0,1); 10]);
86+
let view = arq.build_from_slice(&[0; 10]);
8787

88-
assert_eq!(arq.query(view, 0, 9), (0,10));
88+
assert_eq!(arq.query(view, 0, 9), 0);
8989

9090
arq.update(view, 1, 3, &10);
9191
arq.update(view, 3, 5, &1);
9292

93-
assert_eq!(arq.query(view, 0, 9), (23,10));
94-
assert_eq!(arq.query(view, 10, 4), (0,0));
93+
assert_eq!(arq.query(view, 0, 9), 23);
94+
assert_eq!(arq.query(view, 10, 4), 0);
9595
}
9696

9797
#[test]

‎src/range_query/specs.rs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,21 @@ pub trait ArqSpec {
99
// their parts. This representation is more efficient.
1010
type F: Clone;
1111

12-
/// Require for all a,b,c: op(a, op(b, c)) = op(op(a, b), c)
12+
/// Must satisfy the Associative Law:
13+
/// For all a,b,c, op(a, op(b, c)) = op(op(a, b), c)
1314
fn op(a: &Self::S, b: &Self::S) -> Self::S;
14-
/// Require for all a: op(a, identity()) = op(identity(), a) = a
15+
/// Must satisfy the Identity Law:
16+
/// For all a, op(a, identity()) = op(identity(), a) = a
1517
fn identity() -> Self::S;
16-
/// For eager updates, compose() can be unimplemented!(). For lazy updates:
17-
/// Require for all f,g,a: apply(compose(f, g), a) = apply(f, apply(g, a))
18+
/// For point query / eager updates, compose() can be unimplemented!()
19+
/// For range query / lazy updates, it must satisfy the Composition Law:
20+
/// For all f,g,a, apply(compose(f, g), a) = apply(f, apply(g, a))
1821
fn compose(f: &Self::F, g: &Self::F) -> Self::F;
19-
/// For eager updates, apply() can assume to act on a leaf. For lazy updates:
20-
/// Require for all f,a,b: apply(f, op(a, b)) = op(apply(f, a), apply(f, b))
21-
fn apply(f: &Self::F, a: &Self::S) -> Self::S;
22+
/// For point query / eager updates, apply() can assume it acts on a leaf.
23+
/// For range query / lazy updates, it must satisfy the Distributive Law:
24+
/// For all f,a,b, apply(f, op(a, b)) = op(apply(f, a), apply(f, b))
25+
/// The `size` parameter makes this law easier to satisfy in certain cases.
26+
fn apply(f: &Self::F, a: &Self::S, size: i64) -> Self::S;
2227
}
2328

2429
/// Range Minimum Query (RMQ), a classic application of ARQ.
@@ -42,7 +47,7 @@ impl ArqSpec for AssignMin {
4247
fn compose(&f: &Self::F, _: &Self::F) -> Self::F {
4348
f
4449
}
45-
fn apply(&f: &Self::F, _: &Self::S) -> Self::S {
50+
fn apply(&f: &Self::F, _: &Self::S, _:i64) -> Self::S {
4651
f
4752
}
4853
}
@@ -55,9 +60,9 @@ impl ArqSpec for AssignMin {
5560
///
5661
/// Associated functions will panic on overflow.
5762
//
58-
// Note that the apply() operation on raw entries is undefined: while leaf nodes
59-
// should simply be set to f, internal nodes must be set to f * size_of_subtree.
60-
// Thus, our monoid type S should store the pair (entry, size_of_subtree).
63+
// Note that while the `size` parameter seems necessary to satisfy the
64+
// Distributive Law, it is merely a convenience: in essence what we've done
65+
// is move to the product monoid of tuples (value, size_of_subtree).
6166
//
6267
// In mathematical jargon, we say that constant assignment f(a) = f is not an
6368
// endomorphism on (i64, +) because f(a+b) = f != 2*f = f(a) + f(b).
@@ -66,19 +71,19 @@ impl ArqSpec for AssignMin {
6671
// = (f*s, s) + (f*t, t) = f((a,s)) + f((b,t)).
6772
pub enum AssignSum {}
6873
impl ArqSpec for AssignSum {
69-
type S = (i64,i64);
74+
type S = i64;
7075
type F = i64;
71-
fn op(&(a, s): &Self::S, &(b, t): &Self::S) -> Self::S {
72-
(a + b, s + t)
76+
fn op(&a: &Self::S, &b: &Self::S) -> Self::S {
77+
a + b
7378
}
7479
fn identity() -> Self::S {
75-
(0,0)
80+
0
7681
}
7782
fn compose(&f: &Self::F, _: &Self::F) -> Self::F {
7883
f
7984
}
80-
fn apply(&f: &Self::F, &(_, s): &Self::S) -> Self::S {
81-
(f * s, s)
85+
fn apply(&f: &Self::F, _: &Self::S,size:i64) -> Self::S {
86+
f * size
8287
}
8388
}
8489

@@ -104,7 +109,7 @@ impl ArqSpec for SupplyDemand {
104109
fn compose(_: &Self::F, _: &Self::F) -> Self::F {
105110
unimplemented!()
106111
}
107-
fn apply(&(p_add, o_add): &Self::F, &(p, o, _): &Self::S) -> Self::S {
112+
fn apply(&(p_add, o_add): &Self::F, &(p, o, _): &Self::S, _:i64) -> Self::S {
108113
let p = p + p_add;
109114
let o = o + o_add;
110115
(p, o, p.min(o))

‎src/range_query/static_arq.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ impl<T: ArqSpec> StaticArq<T> {
3737
arq
3838
}
3939

40-
fn apply(&mut self, p: usize, f: &T::F) {
41-
self.val[p] = T::apply(f, &self.val[p]);
40+
fn apply(&mut self, p: usize, f: &T::F,s:i64) {
41+
self.val[p] = T::apply(f, &self.val[p], s);
4242
if let Some(lazy) = self.app.get_mut(p) {
4343
let h = match *lazy {
4444
Some(ref g) => T::compose(f, g),
@@ -50,8 +50,9 @@ impl<T: ArqSpec> StaticArq<T> {
5050

5151
fn push(&mut self, p: usize) {
5252
if let Some(ref f) = self.app[p].take() {
53-
self.apply(p << 1, f);
54-
self.apply(p << 1 | 1, f);
53+
let s = ((self.app.len() + p - 1) / p / 2).next_power_of_two() as i64;
54+
self.apply(p << 1, f, s);
55+
self.apply(p << 1 | 1, f, s);
5556
}
5657
}
5758

@@ -61,8 +62,8 @@ impl<T: ArqSpec> StaticArq<T> {
6162

6263
fn push_to(&mut self, p: usize) {
6364
let one_plus_floor_log_p = (p + 1).next_power_of_two().trailing_zeros();
64-
for s in (1..one_plus_floor_log_p).rev() {
65-
self.push(p >> s);
65+
for i in (1..one_plus_floor_log_p).rev() {
66+
self.push(p >> i);
6667
}
6768
}
6869

@@ -86,20 +87,21 @@ impl<T: ArqSpec> StaticArq<T> {
8687
self.push_to(l);
8788
}
8889
self.push_to(r);
89-
let (mut l0, mut r0) = (1, 1);
90+
let (mut l0, mut r0,mut s) = (1,1, 1);
9091
while l <= r {
9192
if l & 1 == 1 {
92-
self.apply(l, f);
93+
self.apply(l, f, s);
9394
l0 = l0.max(l);
9495
l += 1;
9596
}
9697
if r & 1 == 0 {
97-
self.apply(r, f);
98+
self.apply(r, f, s);
9899
r0 = r0.max(r);
99100
r -= 1;
100101
}
101102
l >>= 1;
102103
r >>= 1;
104+
s <<= 1;
103105
}
104106
self.pull_from(l0);
105107
self.pull_from(r0);

‎tests/codeforces343d.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,13 @@ fn solve<R: io::BufRead, W: io::Write>(scan: &mut Scanner<R>, out: &mut W) {
7474
let mut p = vec![0; n];
7575
dfs(&tree, 0, &mut l, &mut r, &mut p, &mut 0);
7676

77-
let mut arq = StaticArq::<AssignSum>::new(&vec![(0,1); n + 1]);
77+
let mut arq = StaticArq::<AssignSum>::new(&vec![0; n + 1]);
7878
let q = scan.token::<usize>();
7979
for _ in 0..q {
8080
let c = scan.token::<usize>();
8181
let v = scan.token::<usize>() - 1;
82-
let (sum, len) = arq.query(l[v], r[v]);
82+
let len = (r[v] - l[v] + 1) as i64;
83+
let sum = arq.query(l[v], r[v]);
8384
if c == 1 {
8485
if sum != len {
8586
arq.update(p[v], p[v], &0);
@@ -101,4 +102,4 @@ fn main() {
101102
solve(&mut scan, &mut out);
102103

103104
assert_eq!(out, SAMPLE_OUTPUT);
104-
}
105+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /