use rand::Rng;
use std::iter::repeat;
fn main() {
let mut a = vec![71, 29, 13, 74, 90, 8, 30, 25];
let mut b = vec![72, 1, 50, 98, 86, 86, 52, 57];
let mut c = vec![11, 24, 61, 70, 11, 90, 13, 30];
let ans = ways2(&mut a, &mut b, &mut c);
println!("ans = {}", ans);
let nn: i32 = 100;
let vv: i32 = 100;
let test_time: i32 = 5000;
println!("测试开始");
for i in 0..test_time {
let n = rand::thread_rng().gen_range(0, nn) + 1;
let mut a = random_array(n, vv);
let mut b = random_array(n, vv);
let mut c = random_array(n, vv);
let ans1 = ways1(&mut a, &mut b, &mut c);
let ans2 = ways2(&mut a, &mut b, &mut c);
if ans1 != ans2 {
println!("出错了!{}", i);
println!("ans1 = {}", ans1);
println!("ans2 = {}", ans2);
break;
}
}
println!("测试结束");
}
// 暴力方法
// 时间复杂度O(N^3)
// 为了验证
fn ways1(a: &mut Vec<i32>, b: &mut Vec<i32>, c: &mut Vec<i32>) -> i32 {
let n = a.len() as i32;
a.sort();
b.sort();
c.sort();
let mut ans = 0;
for i in 0..n {
let mut j = 0;
while j < n && b[j as usize] <= a[i as usize] * 2 {
if b[j as usize] > a[i as usize] {
let mut k = 0;
while k < n && c[k as usize] <= b[j as usize] * 2 {
if c[k as usize] > b[j as usize] {
ans += 1;
}
k += 1;
}
}
j += 1;
}
}
return ans;
}
// 正式方法
// 时间复杂度O(N * logN)
fn ways2(a: &mut Vec<i32>, b: &mut Vec<i32>, c: &mut Vec<i32>) -> i32 {
let n = a.len() as i32;
a.sort();
b.sort();
c.sort();
// B里面的记录
let mut help: Vec<i32> = repeat(0).take(n as usize).collect();
let mut i = 0;
let mut l = -1;
let mut r = 0;
while i < n {
while l + 1 < n && c[(l + 1) as usize] <= b[i as usize] {
l += 1;
}
while r < n && c[r as usize] <= b[i as usize] * 2 {
r += 1;
}
help[i as usize] = get_max(r - l - 1, 0);
i += 1;
}
for i in 1..n {
help[i as usize] += help[(i - 1) as usize];
}
let mut ans = 0;
let mut i = 0;
let mut l = -1;
let mut r = 0;
while i < n {
while l + 1 < n && b[(l + 1) as usize] <= a[i as usize] {
l += 1;
}
while r < n && b[r as usize] <= a[i as usize] * 2 {
r += 1;
}
if r - l - 1 > 0 {
ans += sum(&mut help, l + 1, r - 1);
}
i += 1;
}
return ans;
}
fn sum(help: &mut Vec<i32>, l: i32, r: i32) -> i32 {
return if l == 0 {
help[r as usize]
} else {
help[r as usize] - help[(l - 1) as usize]
};
}
fn get_max<T: Clone + Copy + std::cmp::PartialOrd>(a: T, b: T) -> T {
if a > b {
a
} else {
b
}
}
// 为了测试
fn random_array(n: i32, v: i32) -> Vec<i32> {
let mut arr: Vec<i32> = vec![];
for _i in 0..n {
arr.push(rand::thread_rng().gen_range(0, v));
}
return arr;
}
评论