macro_rules! input {
(from $iter:expr, $($r:tt)*) => {
input_inner!{$iter, $($r)*}
};
(source = $s:expr, $($r:tt)*) => {
let mut iter = $s.split_whitespace();
input_inner!{iter, $($r)*}
};
($($r:tt)*) => {
let s = {
use std::io::Read;
let mut s = String::new();
std::io::stdin().read_to_string(&mut s).unwrap();
s
};
let mut iter = s.split_whitespace();
input_inner!{iter, $($r)*}
};
}
macro_rules! input_inner {
($iter:expr) => {};
($iter:expr, ) => {};
($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
let $var = read_value!($iter, $t);
input_inner!{$iter $($r)*}
};
}
macro_rules! read_value {
($iter:expr, ( $($t:tt),* )) => {
( $(read_value!($iter, $t)),* )
};
($iter:expr, [ $t:tt ; $len:expr ]) => {
(0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
};
($iter:expr, chars) => {
read_value!($iter, String).chars().collect::<Vec<char>>()
};
($iter:expr, usize1) => {
read_value!($iter, usize) - 1
};
($iter:expr, $t:ty) => {
$iter.next().unwrap().parse::<$t>().expect("Parse error")
};
}
use std::collections::LinkedList;
type Ptr = usize;
#[derive(Debug)]
struct Node {
idx: usize,
value: usize,
neighbors: LinkedList<Ptr>,
parents: LinkedList<Ptr>,
max_path: usize,
}
fn dfs(node_idx: usize, nodes: &mut Vec<Node>) {
let neighbors = nodes[node_idx].neighbors.clone();
let current_max_path = nodes[node_idx].max_path;
for &neighbor_idx in &neighbors {
let new_max_path = current_max_path + 1;
if nodes[neighbor_idx].max_path <= new_max_path {
nodes[neighbor_idx].max_path = new_max_path;
dfs(neighbor_idx, nodes);
}
}
}
fn main() {
input! {
n: usize,
a: [usize; n],
}
let a = a.repeat(2);
let mut nodes = a
.iter()
.enumerate()
.map(|(idx, &value)| Node {
idx,
value,
neighbors: LinkedList::new(),
parents: LinkedList::new(),
max_path: 1,
})
.collect::<Vec<_>>();
let mut nodes_buffer: Vec<usize> = Vec::with_capacity(a.len());
for i in 0..nodes.len() {
while let Some(&parent_node_idx) = nodes_buffer.last() {
if nodes[i].value > nodes[parent_node_idx].value {
nodes_buffer.pop();
let node_idx = nodes[i].idx;
if node_idx - parent_node_idx < n {
nodes[node_idx].parents.push_back(parent_node_idx);
nodes[parent_node_idx].neighbors.push_back(node_idx);
}
} else {
break;
}
}
nodes_buffer.push(nodes[i].idx);
}
let start_nodes = nodes
.iter()
.filter(|node| node.parents.is_empty())
.map(|node| node.idx)
.collect::<Vec<_>>();
for &node in start_nodes.iter() {
dfs(node, &mut nodes);
}
// eprintln!("{nodes:#?}");
// eprintln!("{start_nodes:?}");
println!("{}", nodes.iter().map(|node| node.max_path).max().unwrap());
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | macro_rules! input { (from $iter:expr, $($r:tt)*) => { input_inner!{$iter, $($r)*} }; (source = $s:expr, $($r:tt)*) => { let mut iter = $s.split_whitespace(); input_inner!{iter, $($r)*} }; ($($r:tt)*) => { let s = { use std::io::Read; let mut s = String::new(); std::io::stdin().read_to_string(&mut s).unwrap(); s }; let mut iter = s.split_whitespace(); input_inner!{iter, $($r)*} }; } macro_rules! input_inner { ($iter:expr) => {}; ($iter:expr, ) => {}; ($iter:expr, $var:ident : $t:tt $($r:tt)*) => { let $var = read_value!($iter, $t); input_inner!{$iter $($r)*} }; } macro_rules! read_value { ($iter:expr, ( $($t:tt),* )) => { ( $(read_value!($iter, $t)),* ) }; ($iter:expr, [ $t:tt ; $len:expr ]) => { (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>() }; ($iter:expr, chars) => { read_value!($iter, String).chars().collect::<Vec<char>>() }; ($iter:expr, usize1) => { read_value!($iter, usize) - 1 }; ($iter:expr, $t:ty) => { $iter.next().unwrap().parse::<$t>().expect("Parse error") }; } use std::collections::LinkedList; type Ptr = usize; #[derive(Debug)] struct Node { idx: usize, value: usize, neighbors: LinkedList<Ptr>, parents: LinkedList<Ptr>, max_path: usize, } fn dfs(node_idx: usize, nodes: &mut Vec<Node>) { let neighbors = nodes[node_idx].neighbors.clone(); let current_max_path = nodes[node_idx].max_path; for &neighbor_idx in &neighbors { let new_max_path = current_max_path + 1; if nodes[neighbor_idx].max_path <= new_max_path { nodes[neighbor_idx].max_path = new_max_path; dfs(neighbor_idx, nodes); } } } fn main() { input! { n: usize, a: [usize; n], } let a = a.repeat(2); let mut nodes = a .iter() .enumerate() .map(|(idx, &value)| Node { idx, value, neighbors: LinkedList::new(), parents: LinkedList::new(), max_path: 1, }) .collect::<Vec<_>>(); let mut nodes_buffer: Vec<usize> = Vec::with_capacity(a.len()); for i in 0..nodes.len() { while let Some(&parent_node_idx) = nodes_buffer.last() { if nodes[i].value > nodes[parent_node_idx].value { nodes_buffer.pop(); let node_idx = nodes[i].idx; if node_idx - parent_node_idx < n { nodes[node_idx].parents.push_back(parent_node_idx); nodes[parent_node_idx].neighbors.push_back(node_idx); } } else { break; } } nodes_buffer.push(nodes[i].idx); } let start_nodes = nodes .iter() .filter(|node| node.parents.is_empty()) .map(|node| node.idx) .collect::<Vec<_>>(); for &node in start_nodes.iter() { dfs(node, &mut nodes); } // eprintln!("{nodes:#?}"); // eprintln!("{start_nodes:?}"); println!("{}", nodes.iter().map(|node| node.max_path).max().unwrap()); } |
English