| Task: | Kyselyt |
| Sender: | Hennkka |
| Submission time: | 2020-10-18 11:40:42 +0300 |
| Language: | Rust |
| Status: | READY |
| Result: | 100 |
| group | verdict | score |
|---|---|---|
| #1 | ACCEPTED | 12 |
| #2 | ACCEPTED | 34 |
| #3 | ACCEPTED | 54 |
| test | verdict | time | group | |
|---|---|---|---|---|
| #1 | ACCEPTED | 0.01 s | 1, 2, 3 | details |
| #2 | ACCEPTED | 0.48 s | 2, 3 | details |
| #3 | ACCEPTED | 0.48 s | 3 | details |
| #4 | ACCEPTED | 0.58 s | 3 | details |
| #5 | ACCEPTED | 0.46 s | 3 | details |
Compiler report
warning: unused import: `std::ops::*`
--> input/code.rs:3:5
|
3 | use std::ops::*;
| ^^^^^^^^^^^
|
= note: `#[warn(unused_imports)]` on by default
warning: unused variable: `n`
--> input/code.rs:8:9
|
8 | let n = input.len();
| ^ help: consider prefixing with an underscore: `_n`
|
= note: `#[warn(unused_variables)]` on by default
warning: unused variable: `n`
--> input/code.rs:95:9
|
95 | let n: usize = nq.next().unwrap();
| ^ help: consider prefixing with an underscore: `_n`
warning: function is never used: `solve_brute`
--> input/code.rs:7:4
|
7 | fn solve_brute(input: Vec<u64>, queries: Vec<(usize, usize)>) -> Vec<u64> {
| ^^^^^^^^^^^
|
= note: `#[warn(dead_code)]` on by defaultCode
use std::io::BufRead;
use std::iter::*;
use std::ops::*;
const MAX_JUMPS: usize = 20;
fn solve_brute(input: Vec<u64>, queries: Vec<(usize, usize)>) -> Vec<u64> {
let n = input.len();
let input: Vec<_> = once(1_000_000_000).chain(input.into_iter()).collect();
queries
.into_iter()
.map(|(a, b)| {
let mut h = input[a];
let mut res = 0;
for i in a..=b {
if input[i] < h {
res += h - input[i];
} else {
h = input[i];
}
}
res
})
.collect()
}
fn solve(input: Vec<u64>, queries: Vec<(usize, usize)>) -> Vec<u64> {
let n = input.len();
let input: Vec<_> = once(1_000_000_000_000)
.chain(input.into_iter())
.chain(once(1_000_000_000_000))
.collect();
// Compute sum table
let mut sums = vec![0; (2 + n) * MAX_JUMPS];
for i in 1..=n + 1 {
sums[i] = sums[i - 1] + input[i];
}
// Compute forward jumps
let mut forward_jump_targets = vec![0; (2 + n) * MAX_JUMPS];
let mut forward_jump_costs = vec![0; (2 + n) * MAX_JUMPS];
{
let mut ends = vec![n + 1];
for i in (1..=n).rev() {
while input[*ends.last().unwrap()] <= input[i] {
ends.pop();
}
let target = *ends.last().unwrap();
forward_jump_targets[i * MAX_JUMPS + 0] = target;
forward_jump_costs[i * MAX_JUMPS + 0] =
input[i] * ((target - i - 1) as u64) - (sums[target - 1] - sums[i]);
ends.push(i);
}
forward_jump_targets[(n + 1) * MAX_JUMPS + 0] = n + 1;
for length in 1..MAX_JUMPS {
forward_jump_targets[(n + 1) * MAX_JUMPS + length] = n + 1;
for i in 1..=n {
let t1 = forward_jump_targets[i * MAX_JUMPS + length - 1];
let t2 = forward_jump_targets[t1 * MAX_JUMPS + length - 1];
forward_jump_targets[i * MAX_JUMPS + length] = t2;
forward_jump_costs[i * MAX_JUMPS + length] = forward_jump_costs
[i * MAX_JUMPS + length - 1]
+ forward_jump_costs[t1 * MAX_JUMPS + length - 1];
}
}
}
queries
.into_iter()
.map(|(a, b)| {
let mut res = 0;
let mut cur = a;
for length in (0..MAX_JUMPS).rev() {
while forward_jump_targets[cur * MAX_JUMPS + length] <= b {
res += forward_jump_costs[cur * MAX_JUMPS + length];
cur = forward_jump_targets[cur * MAX_JUMPS + length];
}
}
if cur < b {
res += ((b - cur) as u64) * input[cur] - (sums[b] - sums[cur]);
}
res
})
.collect()
}
fn main() {
let stdin = std::io::stdin();
let stdin = stdin.lock();
let mut lines = stdin.lines();
let nq = lines.next().unwrap().unwrap();
let mut nq = nq.split_whitespace().map(|v| v.parse().unwrap());
let n: usize = nq.next().unwrap();
let q: usize = nq.next().unwrap();
let input = lines
.next()
.unwrap()
.unwrap()
.split_whitespace()
.map(|v| v.parse().unwrap())
.collect();
let queries = lines
.take(q)
.map(|line| {
line.unwrap()
.split_whitespace()
.map(|v| v.parse().unwrap())
.collect::<Vec<_>>()
})
.map(|v| (v[0], v[1]))
.collect();
for res in solve(input, queries) {
println!("{}", res);
}
}
#[cfg(test)]
mod tests {
use super::*;
fn construct_queries(n: usize) -> Vec<(usize, usize)> {
let mut res = vec![];
for a in 1..=n {
for b in a..=n {
res.push((a, b));
}
}
res
}
#[test]
fn test_sample() {
assert_eq!(
solve(vec![2, 10, 4, 2, 5], vec![(3, 5), (2, 2), (1, 4)]),
vec![2, 0, 14]
);
}
#[test]
fn test_manual() {
let arr = vec![5, 10, 5, 2, 6, 11, 8, 10, 2, 1, 0, 3, 4];
assert_eq!(
solve(arr.clone(), construct_queries(arr.len())),
solve_brute(arr.clone(), construct_queries(arr.len())),
);
}
#[test]
fn test_semi_increasing() {
let arr = vec![0, 2, 1, 4, 3, 6, 5, 8, 7, 10, 9];
assert_eq!(
solve(arr.clone(), construct_queries(arr.len())),
solve_brute(arr.clone(), construct_queries(arr.len())),
);
}
#[test]
fn test_semi_decreasing() {
let mut arr = vec![0, 2, 1, 4, 3, 6, 5, 8, 7, 10, 9];
arr.reverse();
assert_eq!(
solve(arr.clone(), construct_queries(arr.len())),
solve_brute(arr.clone(), construct_queries(arr.len())),
);
}
#[test]
fn test_smallish_random() {
use rand::{distributions::uniform::Uniform, prelude::*};
let mut rng = rand::thread_rng();
let n = 200_000;
let q = 200;
let input_dist = Uniform::new_inclusive(0, 1_000_000_000);
let query_dist = Uniform::new_inclusive(1, n);
let input: Vec<_> = repeat_with(|| rng.sample(input_dist)).take(n).collect();
let queries: Vec<_> = repeat_with(|| (rng.sample(query_dist), rng.sample(query_dist)))
.map(|(a, b)| if a <= b { (a, b) } else { (b, a) })
.take(q)
.collect();
assert_eq!(
solve(input.clone(), queries.clone()),
solve_brute(input, queries)
);
}
#[test]
fn test_large() {
use rand::{distributions::uniform::Uniform, prelude::*};
let mut rng = rand::thread_rng();
let n = 200_000;
let q = 200_000;
let input_dist = Uniform::new_inclusive(0, 1_000_000_000);
let query_dist = Uniform::new_inclusive(1, n);
let input: Vec<_> = repeat_with(|| rng.sample(input_dist)).take(n).collect();
let queries: Vec<_> = repeat_with(|| (rng.sample(query_dist), rng.sample(query_dist)))
.map(|(a, b)| if a <= b { (a, b) } else { (b, a) })
.take(q)
.collect();
solve(input, queries);
}
}
Test details
Test 1
Group: 1, 2, 3
Verdict: ACCEPTED
| input |
|---|
| 100 100 70 8 72 88 42 78 85 41 23 36 6... |
| correct output |
|---|
| 99 0 922 2579 1892 ... |
| user output |
|---|
| 99 0 922 2579 1892 ... Truncated |
Test 2
Group: 2, 3
Verdict: ACCEPTED
| input |
|---|
| 200000 200000 98 99 29 92 29 81 100 52 89 80... |
| correct output |
|---|
| 1497732 2810356 9532632 6655773 5403513 ... |
| user output |
|---|
| 1497732 2810356 9532632 6655773 5403513 ... Truncated |
Test 3
Group: 3
Verdict: ACCEPTED
| input |
|---|
| 200000 200000 818377786 934884634 816080381 ... |
| correct output |
|---|
| 86877225712611 94684086875470 92703793485296 38149694892093 61948503092286 ... |
| user output |
|---|
| 86877225712611 94684086875470 92703793485296 38149694892093 61948503092286 ... Truncated |
Test 4
Group: 3
Verdict: ACCEPTED
| input |
|---|
| 200000 200000 1 2 3 4 5 6 7 8 9 10 11 12 13 ... |
| correct output |
|---|
| 0 0 0 0 0 ... |
| user output |
|---|
| 0 0 0 0 0 ... Truncated |
Test 5
Group: 3
Verdict: ACCEPTED
| input |
|---|
| 200000 200000 200000 199999 199998 199997 19... |
| correct output |
|---|
| 15920862903 3193483321 18874982071 4846348926 3970697055 ... |
| user output |
|---|
| 15920862903 3193483321 18874982071 4846348926 3970697055 ... Truncated |
