Problem:
Score : 100 points

Problem Statement

You are given a grid of N rows and M columns. The square at the i-th row and j-th column will be denoted as (i,j).
Some of the squares contain an object. All the remaining squares are empty.
The state of the grid is represented by strings S_1,S_2,\cdots,S_N. The square (i,j) contains an object if S_{i,j}= # and is empty if S_{i,j}= ..

Consider placing 1 \times 2 tiles on the grid. Tiles can be placed vertically or horizontally to cover two adjacent empty squares.
Tiles must not stick out of the grid, and no two different tiles may intersect. Tiles cannot occupy the square with an object.

Calculate the maximum number of tiles that can be placed and any configulation that acheives the maximum.

Constraints

1 \leq N \leq 100

1 \leq M \leq 100

S_i is a string with length M consists of # and ..

Input

Input is given from Standard Input in the following format:

N M
S_1
S_2
\vdots
S_N

Output

On the first line, print the maximum number of tiles that can be placed.

On the next N lines, print a configulation that achieves the maximum.
Precisely, output the strings t_1,t_2,\cdots,t_N constructed by the following way.

t_i is initialized to S_i.

For each (i,j), if there is a tile that occupies (i,j) and (i+1,j), change t_{i,j}:=v, t_{i+1,j}:=^.

For each (i,j), if there is a tile that occupies (i,j) and (i,j+1), change t_{i,j}:=>, t_{i,j+1}:=<.

See samples for further information.

You may print any configulation that maximizes the number of tiles.

Sample Input 1

3 3
#..
..#
...

Sample Output 1

3
#><
vv#
^^.

The following output is also treated as a correct answer.

3
#><
v.#
^><

Solution in Rust (1.42.0) (judge verdict: Runtime Error)

use competitive_programming_rs :: graph :: maximum_flow :: dinitz :: Dinitz ; fn main () { let (r , w) = (std :: io :: stdin () , std :: io :: stdout ()) ; let mut sc = IO :: new (r . lock () , w . lock ()) ; let n : usize = sc . read () ; let m : usize = sc . read () ; let mut map : Vec < Vec < char > > = (0 .. n) . map (| _ | sc . chars ()) . collect () ; let mut dinitz = Dinitz :: new (m * n + 2) ; let source = m * n ; let sink = source + 1 ; for i in 0 .. n { for j in 0 .. m { if map [i] [j] == '#' { continue ; } let v = i * m + j ; if (i + j) % 2 == 0 { dinitz . add_edge (source , v , 1) ; for & (di , dj) in [(0 , ! 0) , (0 , 1) , (1 , 0) , (! 0 , 1)] . iter () { let ni = i . wrapping_add (di) ; let nj = j . wrapping_add (dj) ; if ni >= n || nj >= m { continue ; } dinitz . add_edge (v , ni * m + nj , 1) ; } } else { dinitz . add_edge (v , sink , 1) ; } } } let flow = dinitz . max_flow (source , sink) ; for from in 0 .. (m * n) { for e in dinitz . g [from] . iter () { if e . is_reversed || e . cap > 0 || e . to == sink { continue ; } let (from_i , from_j) = (from / n , from % m) ; let (to_i , to_j) = (e . to / n , e . to % m) ; assert_eq ! (map [from_i] [from_j] , '.') ; assert_eq ! (map [to_i] [to_j] , '.') ; if from_i < to_i { assert_eq ! (from_j , to_j) ; map [from_i] [from_j] = 'v' ; map [to_i] [to_j] = '^' ; } else if from_i > to_i { assert_eq ! (from_j , to_j) ; map [from_i] [from_j] = '^' ; map [to_i] [to_j] = 'v' ; } else if from_j < to_j { map [from_i] [from_j] = '>' ; map [to_i] [to_j] = '<' ; } else { map [from_i] [from_j] = '<' ; map [to_i] [to_j] = '>' ; } } } sc . write (flow) ; sc . write ('\n') ; for i in 0 .. n { for j in 0 .. m { sc . write (map [i] [j]) ; } sc . write ('\n') ; } } pub struct IO < R , W : std :: io :: Write > (R , std :: io :: BufWriter < W >) ; impl < R : std :: io :: Read , W : std :: io :: Write > IO < R , W > { pub fn new (r : R , w : W) -> Self { Self (r , std :: io :: BufWriter :: new (w)) } pub fn write < S : ToString > (& mut self , s : S) { use std :: io :: Write ; self . 1 . write_all (s . to_string () . as_bytes ()) . unwrap () ; } pub fn read < T : std :: str :: FromStr > (& mut self) -> T { use std :: io :: Read ; let buf = self . 0 . by_ref () . bytes () . map (| b | b . unwrap ()) . skip_while (| & b | b == b' ' || b == b'\n' || b == b'\r' || b == b'\t') . take_while (| & b | b != b' ' && b != b'\n' && b != b'\r' && b != b'\t') . collect :: < Vec < _ > > () ; unsafe { std :: str :: from_utf8_unchecked (& buf) } . parse () . ok () . expect ("Parse error.") } pub fn vec < T : std :: str :: FromStr > (& mut self , n : usize) -> Vec < T > { (0 .. n) . map (| _ | self . read ()) . collect () } pub fn chars (& mut self) -> Vec < char > { self . read :: < String > () . chars () . collect () } }mod competitive_programming_rs { # ! [doc = " # The Competitive Programming Library in Rust"] # ! [doc = " The Competitive Programming Library in Rust is a set of snippets,"] # ! [doc = " which can be used in programming contests."] # ! [allow (clippy :: module_inception)] # ! [allow (clippy :: suspicious_arithmetic_impl)] # [doc = " Algorithms related to graph theory."] pub mod graph { pub mod bridge_detection { pub struct BridgeDetector { articulations : Vec < usize > , bridges : Vec < (usize , usize) > , visit : Vec < bool > , order : Vec < usize > , low_link : Vec < usize > , k : usize , } impl BridgeDetector { pub fn new (graph : & [Vec < usize >]) -> Self { let n = graph . len () ; let mut d = BridgeDetector { articulations : vec ! [] , bridges : vec ! [] , visit : vec ! [false ; n] , order : vec ! [0 ; n] , low_link : vec ! [0 ; n] , k : 0 , } ; d . run (graph) ; d } fn run (& mut self , graph : & [Vec < usize >]) { let n = graph . len () ; for i in 0 .. n { if ! self . visit [i] { self . dfs (i , 0 , graph , i) ; } } } fn dfs (& mut self , v : usize , previous : usize , graph : & [Vec < usize >] , root : usize) { self . visit [v] = true ; self . order [v] = self . k ; self . k += 1 ; self . low_link [v] = self . order [v] ; let mut is_articulation = false ; let mut dimension = 0 ; for & next in graph [v] . iter () { if ! self . visit [next] { dimension += 1 ; self . dfs (next , v , graph , root) ; self . low_link [v] = std :: cmp :: min (self . low_link [v] , self . low_link [next]) ; if v != root && self . order [v] <= self . low_link [next] { is_articulation = true ; } if self . order [v] < self . low_link [next] { let min = std :: cmp :: min (v , next) ; let max = std :: cmp :: max (v , next) ; self . bridges . push ((min , max)) ; } } else if v == root || next != previous { self . low_link [v] = std :: cmp :: min (self . low_link [v] , self . order [next]) ; } } if v == root && dimension > 1 { is_articulation = true ; } if is_articulation { self . articulations . push (v) ; } } } # [cfg (test)] mod tests { use super :: * ; use crate :: utils :: test_helper :: Tester ; # [test] fn solve_grl_3_a () { let tester = Tester :: new ("./assets/GRL_3_A/in/" , "./assets/GRL_3_A/out/") ; tester . test_solution (| sc | { let n : usize = sc . read () ; let m : usize = sc . read () ; let mut graph = vec ! [vec ! [] ; n] ; for _ in 0 .. m { let u : usize = sc . read () ; let v : usize = sc . read () ; graph [u] . push (v) ; graph [v] . push (u) ; } let mut low_link_link = BridgeDetector :: new (& graph) ; low_link_link . articulations . sort () ; for v in low_link_link . articulations . into_iter () { sc . write (format ! ("{}\n" , v)) ; } }) ; } # [test] fn solve_grl_3_b () { let tester = Tester :: new ("./assets/GRL_3_B/in/" , "./assets/GRL_3_B/out/") ; tester . test_solution (| sc | { let n : usize = sc . read () ; let m : usize = sc . read () ; let mut graph = vec ! [vec ! [] ; n] ; for _ in 0 .. m { let u : usize = sc . read () ; let v : usize = sc . read () ; graph [u] . push (v) ; graph [v] . push (u) ; } let mut low_link_link = BridgeDetector :: new (& graph) ; low_link_link . bridges . sort () ; for (a , b) in low_link_link . bridges . into_iter () { sc . write (format ! ("{} {}\n" , a , b)) ; } }) ; } } } pub mod cost_scaling_push_relabel { pub mod cost_scaling_push_relabel { use std :: collections :: VecDeque ; type Flow = i64 ; type Cost = i64 ; const INF_POTENTIAL : f64 = 1e10 ; const SCALING_FACTOR : f64 = 2.0 ; # [derive (Clone)] struct Edge { to : usize , rev : usize , flow : Flow , capacity : Flow , cost : Cost , is_rev : bool , } impl Edge { fn residual (& self) -> Flow { self . capacity - self . flow } } # [derive (Clone)] struct Node { excess_flow : Flow , potential : f64 , } pub struct Solver { nodes : Vec < Node > , graph : Vec < Vec < Edge > > , active_nodes : VecDeque < usize > , cost_scaling_factor : f64 , eps : f64 , } impl Solver { pub fn new (num_nodes : usize) -> Self { Self { nodes : vec ! [Node { excess_flow : 0 , potential : 0.0 } ; num_nodes] , graph : vec ! [vec ! [] ; num_nodes] , active_nodes : VecDeque :: new () , eps : 1.0 , cost_scaling_factor : num_nodes as f64 * 2.0 , } } pub fn add_edge (& mut self , from : usize , to : usize , capacity : Flow , cost : Cost) { let rev = self . graph [to] . len () ; self . graph [from] . push (Edge { to , rev , flow : 0 , capacity , cost , is_rev : false , }) ; let rev = self . graph [from] . len () - 1 ; self . graph [to] . push (Edge { to : from , rev , flow : capacity , capacity , cost : - cost , is_rev : true , }) ; self . eps = max (self . eps , cost . abs () as f64 * self . cost_scaling_factor) ; } pub fn solve (& mut self , source : usize , sink : usize , flow : Flow) -> Flow { self . nodes [source] . excess_flow = flow ; self . nodes [sink] . excess_flow = - flow ; while self . eps > 1.0 { for node in 0 .. self . nodes . len () { for edge in 0 .. self . graph [node] . len () { if self . graph [node] [edge] . is_rev { continue ; } let reduced_cost = self . calc_reduced_cost (node , edge) ; if reduced_cost < 0.0 && self . graph [node] [edge] . residual () > 0 { let f = self . graph [node] [edge] . residual () ; self . push_flow (node , edge , f) ; } if reduced_cost > 0.0 && self . graph [node] [edge] . flow > 0 { let f = - self . graph [node] [edge] . flow ; self . push_flow (node , edge , f) ; } } } self . get_active_nodes () ; while let Some (node) = self . active_nodes . pop_front () { while self . nodes [node] . excess_flow > 0 { if ! self . push (node) { self . relabel (node) ; self . active_nodes . push_back (node) ; break ; } } } self . eps = max (1.0 , self . eps / SCALING_FACTOR) ; } let mut total_cost = 0 ; for e in self . graph . iter () . flat_map (| g | g . iter ()) { if e . is_rev { continue ; } total_cost += e . flow * e . cost ; } total_cost } fn push_flow (& mut self , node : usize , edge : usize , flow : Flow) { self . graph [node] [edge] . flow += flow ; let to = self . graph [node] [edge] . to ; let rev = self . graph [node] [edge] . rev ; let from = node ; self . graph [to] [rev] . flow -= flow ; self . nodes [from] . excess_flow -= flow ; self . nodes [to] . excess_flow += flow ; } fn calc_reduced_cost (& self , node : usize , edge : usize) -> f64 { let cost = self . graph [node] [edge] . cost ; let from = node ; let to = self . graph [node] [edge] . to ; cost as f64 * self . cost_scaling_factor - self . nodes [from] . potential + self . nodes [to] . potential } fn get_active_nodes (& mut self) { for u in 0 .. self . nodes . len () { if self . nodes [u] . excess_flow > 0 { self . active_nodes . push_back (u) ; } } } fn push (& mut self , from : usize) -> bool { if self . nodes [from] . excess_flow == 0 { return false ; } assert ! (self . nodes [from] . excess_flow > 0) ; for i in (0 .. self . graph [from] . len ()) . rev () { if self . graph [from] [i] . residual () == 0 { continue ; } let reduced_cost = self . calc_reduced_cost (from , i) ; if reduced_cost < 0.0 { let flow = min (self . graph [from] [i] . residual () , self . nodes [from] . excess_flow) ; self . push_flow (from , i , flow) ; let to = self . graph [from] [i] . to ; if self . nodes [to] . excess_flow > 0 && self . nodes [to] . excess_flow <= flow { self . active_nodes . push_back (to) ; } return true ; } } false } fn relabel (& mut self , from : usize) { let mut min_potential = INF_POTENTIAL ; for e in self . graph [from] . iter () { if e . residual () > 0 { min_potential = min (min_potential , e . cost as f64 * self . cost_scaling_factor + self . nodes [e . to] . potential + self . eps ,) ; } } assert ! (min_potential < INF_POTENTIAL) ; self . nodes [from] . potential = min_potential ; } } fn min < T : PartialOrd > (a : T , b : T) -> T { if a > b { b } else { a } } fn max < T : PartialOrd > (a : T , b : T) -> T { if a < b { b } else { a } } } # [cfg (test)] mod tests { use crate :: graph :: cost_scaling_push_relabel :: cost_scaling_push_relabel ; use crate :: graph :: min_cost_flow :: primal_dual ; use crate :: utils :: test_helper :: Tester ; # [test] fn solve_grl_6_b () { let tester = Tester :: new ("./assets/GRL_6_B/in/" , "./assets/GRL_6_B/out/") ; tester . test_solution (| sc | { let v : usize = sc . read () ; let e : usize = sc . read () ; let f : i64 = sc . read () ; let mut solver = cost_scaling_push_relabel :: Solver :: new (v) ; let mut verify = primal_dual :: MinimumCostFlowSolver :: new (v) ; for _ in 0 .. e { let u : usize = sc . read () ; let v : usize = sc . read () ; let c : i64 = sc . read () ; let d : i64 = sc . read () ; solver . add_edge (u , v , c , d) ; verify . add_edge (u , v , c , d) ; } match verify . solve (0 , v - 1 , f) { Some (ans) => { sc . write (format ! ("{}\n" , ans)) ; assert_eq ! (ans , solver . solve (0 , v - 1 , f)) ; } _ => { sc . write ("-1\n") ; } } }) ; } } } pub mod lca { pub mod lca { const MAX_PARENT : usize = 1 << 50 ; pub struct LowestCommonAncestor { parent : Vec < Vec < usize > > , depth : Vec < usize > , log_v : usize , } impl LowestCommonAncestor { pub fn new (graph : & [Vec < usize >]) -> Self { let num_v = graph . len () ; let root = 0 ; let mut depth = vec ! [0 ; num_v] ; let mut log_v = 1 ; let mut i = 1 ; while i <= num_v { i *= 2 ; log_v += 1 ; } let mut parent : Vec < Vec < usize > > = vec ! [vec ! [0 ; num_v] ; log_v] ; let mut depth_vis = vec ! [false ; num_v] ; let mut stack = :: std :: collections :: VecDeque :: new () ; stack . push_front (root) ; parent [0] [root] = MAX_PARENT ; depth [root] = 0 ; depth_vis [root] = true ; while ! stack . is_empty () { let v = stack . pop_front () . unwrap () ; stack . push_front (v) ; for & u in & graph [v] { if depth_vis [u] { continue ; } parent [0] [u] = v ; depth [u] = depth [v] + 1 ; depth_vis [u] = true ; stack . push_front (u) ; } let head = stack . pop_front () . unwrap () ; if head != v { stack . push_front (head) ; } } for k in 0 .. (log_v - 1) { for u in 0 .. num_v { parent [k + 1] [u] = if parent [k] [u] == MAX_PARENT { MAX_PARENT } else { parent [k] [parent [k] [u]] } ; } } LowestCommonAncestor { parent , depth , log_v , } } pub fn get_lca (& self , u : usize , v : usize) -> usize { let (mut u , mut v) = if self . depth [u] <= self . depth [v] { (u , v) } else { (v , u) } ; for k in 0 .. self . log_v { if ((self . depth [v] - self . depth [u]) & (1 << k)) != 0 { v = self . parent [k] [v] ; } } if u == v { return u ; } for k in (0 .. self . log_v) . rev () { if self . parent [k] [u] != self . parent [k] [v] { u = self . parent [k] [u] ; v = self . parent [k] [v] ; } } self . parent [0] [u] } pub fn get_dist (& self , u : usize , v : usize) -> usize { let lca = self . get_lca (u , v) ; self . depth [u] + self . depth [v] - self . depth [lca] * 2 } } } # [cfg (test)] mod tests { use super :: lca :: * ; use crate :: utils :: test_helper :: Tester ; # [test] fn solve_grl_5_c () { let tester = Tester :: new ("./assets/GRL_5_C/in/" , "./assets/GRL_5_C/out/") ; tester . test_solution (| sc | { let n : usize = sc . read () ; let mut graph = (0 .. n) . map (| _ | Vec :: new ()) . collect :: < Vec < _ > > () ; for i in 0 .. n { let k = sc . read () ; for _ in 0 .. k { let c : usize = sc . read () ; graph [i] . push (c) ; graph [c] . push (i) ; } } let lca = LowestCommonAncestor :: new (& graph) ; let q : usize = sc . read () ; for _ in 0 .. q { let u : usize = sc . read () ; let v : usize = sc . read () ; let ans = lca . get_lca (u , v) ; sc . write (format ! ("{}\n" , ans)) ; } }) ; } } } pub mod maximum_flow { pub mod dinitz { pub struct Edge { pub to : usize , pub rev : usize , pub is_reversed : bool , pub cap : i64 , } pub struct Dinitz { pub g : Vec < Vec < Edge > > , } impl Dinitz { pub fn new (v : usize) -> Dinitz { let mut g : Vec < Vec < Edge > > = Vec :: new () ; for _ in 0 .. v { g . push (Vec :: new ()) ; } Dinitz { g } } pub fn add_edge (& mut self , from : usize , to : usize , cap : i64) { let to_len = self . g [to] . len () ; let from_len = self . g [from] . len () ; self . g [from] . push (Edge { to , rev : to_len , is_reversed : false , cap , }) ; self . g [to] . push (Edge { to : from , rev : from_len , is_reversed : true , cap : 0 , }) ; } fn dfs (& mut self , v : usize , sink : usize , flow : i64 , level : & [i32] , iter : & mut [usize] ,) -> i64 { if v == sink { return flow ; } while iter [v] < self . g [v] . len () { let flow = std :: cmp :: min (flow , self . g [v] [iter [v]] . cap) ; let to = self . g [v] [iter [v]] . to ; if flow > 0 && level [v] < level [to] { let flowed = self . dfs (to , sink , flow , level , iter) ; if flowed > 0 { let rev = self . g [v] [iter [v]] . rev ; self . g [v] [iter [v]] . cap -= flowed ; self . g [to] [rev] . cap += flowed ; return flowed ; } } iter [v] += 1 ; } 0 } fn bfs (& self , s : usize) -> Vec < i32 > { let v = self . g . len () ; let mut level = vec ! [- 1 ; v] ; level [s] = 0 ; let mut deque = std :: collections :: VecDeque :: new () ; deque . push_back (s) ; while let Some (v) = deque . pop_front () { for e in self . g [v] . iter () { if e . cap > 0 && level [e . to] < 0 { level [e . to] = level [v] + 1 ; deque . push_back (e . to) ; } } } level } pub fn max_flow (& mut self , s : usize , t : usize) -> i64 { let v = self . g . len () ; let mut flow : i64 = 0 ; loop { let level = self . bfs (s) ; if level [t] < 0 { return flow ; } let mut iter = vec ! [0 ; v] ; loop { let f = self . dfs (s , t , std :: i64 :: MAX , & level , & mut iter) ; if f == 0 { break ; } flow += f ; } } } } } # [cfg (test)] mod tests { use super :: * ; use crate :: utils :: test_helper :: Tester ; # [doc = " Solve http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=GRL_6_A"] # [test] fn solve_grl_6_a () { let tester = Tester :: new ("./assets/GRL_6_A/in/" , "./assets/GRL_6_A/out/") ; tester . test_solution (| sc | { let v = sc . read () ; let e = sc . read () ; let mut dinitz = dinitz :: Dinitz :: new (v) ; for _ in 0 .. e { let from = sc . read () ; let to = sc . read () ; let c = sc . read () ; dinitz . add_edge (from , to , c) ; } let flow = dinitz . max_flow (0 , v - 1) ; sc . write (format ! ("{}\n" , flow)) ; }) ; } } } pub mod min_cost_flow { pub mod primal_dual { use std :: cmp ; use std :: collections :: BinaryHeap ; use std :: i64 ; type Flow = i64 ; type Cost = i64 ; const INF : Cost = i64 :: MAX >> 3 ; struct Edge { to : usize , capacity : Flow , flow : Flow , cost : Cost , reverse_to : usize , is_reversed : bool , } impl Edge { fn residue (& self) -> Flow { self . capacity - self . flow } } pub struct MinimumCostFlowSolver { graph : Vec < Vec < Edge > > , previous_edge : Vec < (usize , usize) > , } impl MinimumCostFlowSolver { pub fn new (n : usize) -> Self { MinimumCostFlowSolver { graph : (0 .. n) . map (| _ | Vec :: new ()) . collect () , previous_edge : vec ! [(0 , 0) ; n] , } } pub fn add_edge (& mut self , from : usize , to : usize , capacity : Flow , cost : Cost) { let reverse_from = self . graph [to] . len () ; let reverse_to = self . graph [from] . len () ; self . graph [from] . push (Edge { to , capacity , flow : 0 , cost , reverse_to : reverse_from , is_reversed : false , }) ; self . graph [to] . push (Edge { to : from , capacity , flow : capacity , cost : - cost , reverse_to , is_reversed : true , }) ; } pub fn solve (& mut self , source : usize , sink : usize , mut flow : Flow) -> Option < Flow > { let n = self . graph . len () ; let mut result = 0 ; let mut h = vec ! [0 ; n] ; let mut q : BinaryHeap < (Cost , usize) > = BinaryHeap :: new () ; while flow > 0 { let mut dist = vec ! [INF ; n] ; dist [source] = 0 ; q . push ((0 , source)) ; while let Some ((current_dist , v)) = q . pop () { if dist [v] < current_dist { continue ; } for (i , e) in self . graph [v] . iter () . enumerate () { if e . residue () == 0 { continue ; } if dist [e . to] + h [e . to] > current_dist + h [v] + e . cost { dist [e . to] = current_dist + h [v] + e . cost - h [e . to] ; self . previous_edge [e . to] = (v , i) ; q . push ((dist [e . to] , e . to)) ; } } } if dist [sink] == INF { return None ; } for i in 0 .. n { h [i] += dist [i] ; } let mut df = flow ; let mut v = sink ; while v != source { let (prev_v , prev_e) = self . previous_edge [v] ; df = cmp :: min (df , self . graph [prev_v] [prev_e] . residue ()) ; v = prev_v ; } flow -= df ; result += df * h [sink] ; let mut v = sink ; while v != source { let (prev_v , prev_e) = self . previous_edge [v] ; self . graph [prev_v] [prev_e] . flow += df ; let reversed_edge_id = self . graph [prev_v] [prev_e] . reverse_to ; self . graph [v] [reversed_edge_id] . flow -= df ; v = prev_v ; } } Some (result) } pub fn neg_solve (& mut self , source : usize , sink : usize , mut flow : Flow) -> Option < Flow > { let n = self . graph . len () ; let mut result = 0 ; while flow > 0 { let mut dist = vec ! [INF ; n] ; dist [source] = 0 ; loop { let mut updated = false ; for v in 0 .. n { if dist [v] == INF { continue ; } for (i , e) in self . graph [v] . iter () . enumerate () { if e . residue () == 0 { continue ; } if dist [e . to] > dist [v] + e . cost { dist [e . to] = dist [v] + e . cost ; self . previous_edge [e . to] = (v , i) ; updated = true ; } } } if ! updated { break ; } } if dist [sink] == INF { return None ; } let mut df = flow ; let mut v = sink ; while v != source { let (prev_v , prev_e) = self . previous_edge [v] ; df = cmp :: min (df , self . graph [prev_v] [prev_e] . residue ()) ; v = prev_v ; } flow -= df ; result += df * dist [sink] ; let mut v = sink ; while v != source { let (prev_v , prev_e) = self . previous_edge [v] ; self . graph [prev_v] [prev_e] . flow += df ; let reversed_edge_id = self . graph [prev_v] [prev_e] . reverse_to ; self . graph [v] [reversed_edge_id] . flow -= df ; v = prev_v ; } } Some (result) } } } # [cfg (test)] mod tests { use super :: * ; use crate :: utils :: test_helper :: Tester ; # [test] fn solve_grl_6_b () { let tester = Tester :: new ("./assets/GRL_6_B/in/" , "./assets/GRL_6_B/out/") ; tester . test_solution (| sc | { let v : usize = sc . read () ; let e : usize = sc . read () ; let f : i64 = sc . read () ; let mut solver = primal_dual :: MinimumCostFlowSolver :: new (v) ; for _ in 0 .. e { let u : usize = sc . read () ; let v : usize = sc . read () ; let c : i64 = sc . read () ; let d : i64 = sc . read () ; solver . add_edge (u , v , c , d) ; } let ans = match solver . solve (0 , v - 1 , f) { Some (flow) => flow , None => - 1 , } ; sc . write (format ! ("{}\n" , ans)) ; }) ; } # [test] fn solve_grl_6_b_negative () { let tester = Tester :: new ("./assets/GRL_6_B/in/" , "./assets/GRL_6_B/out/") ; tester . test_solution (| sc | { let v : usize = sc . read () ; let e : usize = sc . read () ; let f : i64 = sc . read () ; let mut solver = primal_dual :: MinimumCostFlowSolver :: new (v) ; for _ in 0 .. e { let u : usize = sc . read () ; let v : usize = sc . read () ; let c : i64 = sc . read () ; let d : i64 = sc . read () ; solver . add_edge (u , v , c , d) ; } let ans = match solver . neg_solve (0 , v - 1 , f) { Some (flow) => flow , None => - 1 , } ; sc . write (format ! ("{}\n" , ans)) ; }) ; } } } pub mod shortest_path { pub mod bellman_ford { pub fn shortest_path (graph : & [Vec < (usize , i64) >] , start : usize , inf : i64 ,) -> (Vec < i64 > , Vec < bool >) { let n = graph . len () ; let mut dist = vec ! [inf ; n] ; dist [start] = 0 ; for _ in 0 .. n { for v in 0 .. n { for & (to , cost) in & graph [v] { if dist [v] == inf || dist [to] <= dist [v] + cost { continue ; } dist [to] = dist [v] + cost ; } } } let mut negative = vec ! [false ; n] ; for _ in 0 .. n { for v in 0 .. n { for & (to , cost) in & graph [v] { if dist [v] == inf { continue ; } if dist [to] > dist [v] + cost { dist [to] = dist [v] + cost ; negative [to] = true ; } if negative [v] { negative [to] = true ; } } } } (dist , negative) } } # [cfg (test)] mod tests { use super :: * ; use crate :: utils :: test_helper :: Tester ; use std ; # [test] fn solve_grl_1_b () { let tester = Tester :: new ("./assets/GRL_1_B/in/" , "./assets/GRL_1_B/out/") ; tester . test_solution (| sc | { let v : usize = sc . read () ; let e : usize = sc . read () ; let r : usize = sc . read () ; let mut graph = vec ! [vec ! [] ; v] ; for _ in 0 .. e { let s : usize = sc . read () ; let t : usize = sc . read () ; let d : i64 = sc . read () ; graph [s] . push ((t , d)) ; } let inf = std :: i64 :: MAX ; let (dist , negative) = bellman_ford :: shortest_path (& graph , r , inf) ; let mut neg = false ; for & b in & negative { neg = neg || b ; } if neg { sc . write ("NEGATIVE CYCLE\n") ; } else { for i in 0 .. v { if dist [i] == inf { sc . write ("INF\n") ; } else { sc . write (format ! ("{}\n" , dist [i])) ; } } } }) ; } } } pub mod strongly_connected_components { pub mod strongly_connected_components { use std :: collections :: VecDeque ; pub fn decompose (graph : & [Vec < usize >]) -> Vec < usize > { let mut vs = Vec :: new () ; let num_v = graph . len () ; let mut cmp = vec ! [0 ; num_v] ; let mut reverse_graph = vec ! [vec ! [] ; num_v] ; for (i , edges) in graph . iter () . enumerate () { for & v in edges . iter () { reverse_graph [v] . push (i) ; } } let mut used = vec ! [false ; num_v] ; let mut stack = VecDeque :: new () ; let mut added = vec ! [false ; num_v] ; for i in 0 .. num_v { if used [i] { continue ; } stack . push_front (i) ; while let Some (v) = stack . pop_front () { stack . push_front (v) ; used [v] = true ; let mut pushed = false ; for & u in graph [v] . iter () . rev () { if ! used [u] { stack . push_front (u) ; pushed = true ; } } if ! pushed { stack . pop_front () ; if ! added [v] { vs . push (v) ; added [v] = true ; } } } } used = vec ! [false ; num_v] ; let mut k = 0 ; vs . reverse () ; for & i in vs . iter () { if used [i] { continue ; } stack . push_front (i) ; used [i] = true ; cmp [i] = k ; while let Some (v) = stack . pop_front () { stack . push_front (v) ; let mut pushed = false ; for & u in reverse_graph [v] . iter () { if used [u] { continue ; } used [u] = true ; cmp [u] = k ; stack . push_front (u) ; pushed = true ; } if ! pushed { stack . pop_front () ; } } k += 1 ; } cmp } } # [cfg (test)] mod tests { use super :: * ; use crate :: utils :: test_helper :: Tester ; # [test] fn solve_grl_3_c () { let tester = Tester :: new ("./assets/GRL_3_C/in/" , "./assets/GRL_3_C/out/") ; tester . test_solution (| sc | { let v : usize = sc . read () ; let e : usize = sc . read () ; let mut graph = vec ! [vec ! [] ; v] ; for _ in 0 .. e { let s : usize = sc . read () ; let t : usize = sc . read () ; graph [s] . push (t) ; } let cmp = strongly_connected_components :: decompose (& graph) ; let q : usize = sc . read () ; for _ in 0 .. q { let u : usize = sc . read () ; let v : usize = sc . read () ; if cmp [u] == cmp [v] { sc . write ("1\n") ; } else { sc . write ("0\n") ; } } }) ; } } } } # [doc = " Structures that can efficiently operate data."] pub mod data_structure { pub mod bitset { pub mod bitset { const ONE_VALUE_LENGTH : usize = 63 ; const MAXIMUM : u64 = (1u64 << ONE_VALUE_LENGTH as u64) - 1 ; pub fn get_bit_position (index : usize) -> (usize , usize) { let data_index = index / ONE_VALUE_LENGTH ; let bit_index = index % ONE_VALUE_LENGTH ; (data_index , bit_index) } # [derive (PartialEq , Clone , Debug)] pub struct BitSet { data : Vec < u64 > , } impl std :: ops :: BitOrAssign for BitSet { fn bitor_assign (& mut self , rhs : Self) { if self . data . len () < rhs . data . len () { self . data . resize (rhs . data . len () , 0) ; } let n = if self . data . len () > rhs . data . len () { rhs . data . len () } else { self . data . len () } ; for i in 0 .. n { assert ! (self . data [i] <= MAXIMUM) ; assert ! (rhs . data [i] <= MAXIMUM) ; self . data [i] |= rhs . data [i] ; } } } impl std :: ops :: Shl < usize > for BitSet { type Output = Self ; fn shl (self , rhs : usize) -> Self { self . shift_left (rhs) } } impl BitSet { pub fn new (n : usize) -> Self { let size = (n + ONE_VALUE_LENGTH - 1) / ONE_VALUE_LENGTH ; BitSet { data : vec ! [0 ; size] , } } pub fn new_from (value : u64) -> Self { BitSet { data : vec ! [value] } } pub fn set (& mut self , index : usize , value : bool) { let (data_index , bit_index) = get_bit_position (index) ; assert ! (self . data . len () > data_index) ; if value { self . data [data_index] |= (1 << bit_index) as u64 ; } else { let tmp = MAXIMUM ^ (1 << bit_index) as u64 ; self . data [data_index] &= tmp ; } } pub fn get (& mut self , index : usize) -> bool { let (data_index , bit_index) = get_bit_position (index) ; assert ! (self . data . len () > data_index) ; self . data [data_index] & (1u64 << bit_index as u64) != 0 } pub fn shift_left (& self , shift : usize) -> Self { let mut next_data = Vec :: new () ; let prefix_empty_count = shift / ONE_VALUE_LENGTH ; let shift_count = (shift % ONE_VALUE_LENGTH) as u64 ; for _ in 0 .. prefix_empty_count { next_data . push (0) ; } let mut from_previous = 0 ; let room = ONE_VALUE_LENGTH as u64 - shift_count ; for & data in self . data . iter () { let overflow = (data >> room) << room ; let rest = data - overflow ; let value = (rest << shift_count) + from_previous ; assert ! (value <= MAXIMUM) ; next_data . push (value) ; from_previous = overflow >> room ; } if from_previous > 0 { next_data . push (from_previous) ; } BitSet { data : next_data } } } } # [cfg (test)] mod test { use super :: bitset :: * ; # [test] fn test_set_bit () { let n = 10 ; let value = 717 ; let mut bitset = BitSet :: new (n) ; for i in 0 .. n { if value & (1 << i) != 0 { bitset . set (i , true) ; } } for i in 0 .. n { if value & (1 << i) != 0 { assert ! (bitset . get (i)) ; } else { assert ! (! bitset . get (i)) ; } } } # [test] fn test_bitset_or () { let mut value1 = 717 ; let mut bitset1 = BitSet :: new_from (value1) ; let value2 = 127 ; let bitset2 = BitSet :: new_from (value2) ; value1 |= value2 ; bitset1 |= bitset2 ; for i in 0 .. 50usize { if value1 & (1u64 << i as u64) != 0 { assert ! (bitset1 . get (i)) ; } else { assert ! (! bitset1 . get (i)) ; } } } # [test] fn test_bitset_shift_left () { let value1 = 717 ; let first_shift = 30 ; let second_shift = 40 ; let bitset1 = BitSet :: new_from (value1) << (first_shift + second_shift) ; let bitset2 = BitSet :: new_from (value1 << first_shift as u64) << second_shift ; assert ! (bitset1 == bitset2) ; } } } pub mod fenwick_tree { pub mod fenwick_tree { # [doc = " `FenwickTree` is a data structure that can efficiently update elements"] # [doc = " and calculate prefix sums in a table of numbers."] # [doc = " [https://en.wikipedia.org/wiki/Fenwick_tree](https://en.wikipedia.org/wiki/Fenwick_tree)"] pub struct FenwickTree < T > { n : usize , data : Vec < T > , init : T , } impl < T : Copy + std :: ops :: AddAssign + std :: ops :: Sub < Output = T > > FenwickTree < T > { # [doc = " Constructs a new `FenwickTree`. The size of `FenwickTree` should be specified by `size`."] pub fn new (size : usize , init : T) -> FenwickTree < T > { FenwickTree { n : size + 1 , data : vec ! [init ; size + 1] , init , } } pub fn add (& mut self , k : usize , value : T) { let mut x = k ; while x < self . n { self . data [x] += value ; x |= x + 1 ; } } # [doc = " Returns a sum of range `[l, r)`"] pub fn sum (& self , l : usize , r : usize) -> T { self . sum_one (r) - self . sum_one (l) } # [doc = " Returns a sum of range `[0, k)`"] pub fn sum_one (& self , k : usize) -> T { assert ! (k < self . n , "k={} n={}" , k , self . n) ; let mut result = self . init ; let mut x = k as i32 - 1 ; while x >= 0 { result += self . data [x as usize] ; x = (x & (x + 1)) - 1 ; } result } } } # [cfg (test)] mod test { use super :: fenwick_tree :: FenwickTree ; use rand :: { thread_rng , Rng } ; # [test] fn random_array () { let n = 1000 ; let mut bit = FenwickTree :: new (n , 0) ; let mut v = vec ! [0 ; n] ; for _ in 0 .. 10000 { let value = thread_rng () . gen_range (0 , 1000) ; let k = thread_rng () . gen_range (0 , n) ; v [k] += value ; bit . add (k , value) ; let mut sum = 0 ; for i in 0 .. n { sum += v [i] ; assert_eq ! (sum , bit . sum (0 , i + 1)) ; } } } } } pub mod fibonacci_heap { pub mod fibonacci_heap { fn store_to_map < T , F > (map : & mut std :: collections :: HashMap < usize , Node < T > > , mut node : Node < T > , ordering : F ,) where T : Copy + PartialEq , F : Fn (T , T) -> T , { let d = node . children . len () ; match map . remove (& d) { Some (mut other) => { let node = if (ordering) (node . key , other . key) == node . key { node . children . push (other) ; node } else { other . children . push (node) ; other } ; store_to_map (map , node , ordering) ; } None => { map . insert (d , node) ; } } } pub struct FibonacciHeap < T , F > { pub nodes : Vec < Node < T > > , min_index : usize , ordering : F , } impl < T , F > FibonacciHeap < T , F > where T : Copy + PartialEq , F : Fn (T , T) -> T + Copy , { pub fn new (ordering : F) -> Self { Self { nodes : Vec :: new () , min_index : 0 , ordering , } } pub fn push (& mut self , x : T) { let node = Node :: new (x) ; self . nodes . push (node) ; let cur_min = self . nodes [self . min_index] . key ; if (self . ordering) (cur_min , x) == x { self . min_index = self . nodes . len () - 1 ; } } pub fn pop (& mut self) -> Option < T > { let mut map = std :: collections :: HashMap :: < usize , Node < T > > :: new () ; let mut popped = None ; let mut nodes = Vec :: new () ; std :: mem :: swap (& mut self . nodes , & mut nodes) ; for (i , node) in nodes . into_iter () . enumerate () { if i == self . min_index { popped = Some (node . key) ; for node in node . children . into_iter () { store_to_map (& mut map , node , self . ordering) ; } } else { store_to_map (& mut map , node , self . ordering) ; } } self . nodes = map . into_iter () . map (| (_ , node) | node) . collect () ; if ! self . nodes . is_empty () { let mut min = self . nodes [0] . key ; for i in 0 .. self . nodes . len () { if (self . ordering) (min , self . nodes [i] . key) == self . nodes [i] . key { min = self . nodes [i] . key ; } } self . min_index = self . nodes . iter () . enumerate () . find (| (_ , node) | node . key == min) . unwrap () . 0 ; } else { self . min_index = 0 ; } popped } } # [derive (Debug)] pub struct Node < T > { pub key : T , pub children : Vec < Node < T > > , } impl < T > Node < T > { fn new (x : T) -> Self { Self { key : x , children : Vec :: new () , } } } } # [cfg (test)] mod tests { use super :: fibonacci_heap :: * ; use rand :: Rng ; use std :: cmp ; use std :: collections :: BinaryHeap ; # [test] fn test_fibonacci_heap () { let mut min_heap = FibonacciHeap :: new (cmp :: min) ; min_heap . push (1) ; assert_eq ! (min_heap . pop () , Some (1)) ; min_heap . push (1) ; min_heap . push (2) ; min_heap . push (3) ; assert_eq ! (min_heap . pop () , Some (1)) ; assert_eq ! (min_heap . pop () , Some (2)) ; assert_eq ! (min_heap . pop () , Some (3)) ; min_heap . push (3) ; min_heap . push (2) ; min_heap . push (1) ; assert_eq ! (min_heap . pop () , Some (1)) ; assert_eq ! (min_heap . pop () , Some (2)) ; assert_eq ! (min_heap . pop () , Some (3)) ; } # [test] fn compare_to_binary_heap () { let mut rng = rand :: thread_rng () ; let mut max_heap = FibonacciHeap :: new (cmp :: max) ; let mut binary_heap = BinaryHeap :: new () ; for _ in 0 .. 2000 { let x = rng . gen :: < usize > () % 10 ; if x == 0 { assert_eq ! (max_heap . pop () , binary_heap . pop ()) ; } else { let v = rng . gen :: < u8 > () ; max_heap . push (v) ; binary_heap . push (v) ; } } } } } pub mod persistent_array { pub mod persistent_array { use std :: rc :: Rc ; const N : usize = 20 ; # [derive (Clone)] pub struct Node < T : Clone > { data : Option < T > , children : [Option < Rc < Node < T > > > ; N] , } impl < T : Clone > Node < T > { pub fn new (data : Option < T > , children : [Option < Rc < Node < T > > > ; N]) -> Self { Self { data , children } } } impl < T : Clone > Default for Node < T > { fn default () -> Self { Self { data : None , children : Default :: default () , } } } pub fn set < T : Clone > (index : usize , data : T , node : Option < Rc < Node < T > > >) -> Rc < Node < T > > { if index == 0 { match node { Some (node) => { let new_node = Node :: new (Some (data) , node . children . clone ()) ; Rc :: new (new_node) } None => Rc :: new (Node :: new (Some (data) , Default :: default ())) , } } else { let child = match node . as_ref () . and_then (| node | node . children [index % N] . as_ref ()) { Some (next_node) => set (index / N , data , Some (next_node . clone ())) , None => set (index / N , data , None) , } ; let mut new_node = match node { Some (node) => node . as_ref () . clone () , None => Node :: default () , } ; new_node . children [index % N] = Some (child) ; Rc :: new (new_node) } } pub fn get < T : Clone > (index : usize , node : & Rc < Node < T > >) -> Option < T > { if index == 0 { node . data . clone () } else { match node . children [index % N] . as_ref () { Some (next_node) => get (index / N , next_node) , None => None , } } } } # [cfg (test)] mod tests { use crate :: data_structure :: persistent_array :: persistent_array :: { get , set , Node } ; use rand :: distributions :: Uniform ; use rand :: { thread_rng , Rng } ; use std :: rc :: Rc ; # [test] fn test_persistent_array () { let mut rng = thread_rng () ; let n : usize = 20 ; let mut vs = vec ! [vec ! [None ; n]] ; let mut nodes = vec ! [Rc :: new (Node :: default ())] ; for _ in 0 .. 10000 { let pick = rng . sample (Uniform :: from (0 .. vs . len ())) ; let mut new_vec = vs [pick] . clone () ; let node = nodes [pick] . clone () ; let pos = rng . sample (Uniform :: from (0 .. n)) ; let value : i64 = rng . gen () ; new_vec [pos] = Some (value) ; let new_node = set (pos , value , Some (node)) ; for i in 0 .. n { let expected = new_vec [i] ; let actual = get (i , & new_node) ; assert_eq ! (expected , actual) ; } vs . push (new_vec . clone ()) ; nodes . push (new_node . clone ()) ; let value : i64 = rng . gen () ; new_vec [pos] = Some (value) ; let new_node = set (pos , value , Some (new_node)) ; for i in 0 .. n { let expected = new_vec [i] ; let actual = get (i , & new_node) ; assert_eq ! (expected , actual) ; } vs . push (new_vec . clone ()) ; nodes . push (new_node) ; } } } } pub mod range_add_segment_tree { pub mod range_add_segment_tree { type Range = std :: ops :: Range < usize > ; pub struct RangeAddSegmentTree < T , F > { data : Vec < T > , lazy : Vec < T > , size : usize , f : F , init : T , } impl < T , F > RangeAddSegmentTree < T , F > where T : PartialOrd + :: std :: ops :: Add < Output = T > + :: std :: ops :: Sub < Output = T > + Copy , F : Fn (T , T) -> T + Copy , { pub fn new (n : usize , init : T , f : F , zero : T) -> Self { let size = n . next_power_of_two () ; RangeAddSegmentTree { data : vec ! [init ; size * 2] , lazy : vec ! [zero ; size * 2] , size , init , f , } } pub fn add (& mut self , range : Range , value : T) { self . add_to_range (range , value , 0 , 0 .. self . size) ; } fn add_to_range (& mut self , add_range : Range , value : T , mut k : usize , seg_range : Range) { if add_range . end <= seg_range . start || seg_range . end <= add_range . start { return ; } if add_range . start <= seg_range . start && seg_range . end <= add_range . end { self . lazy [k] = self . lazy [k] + value ; while k > 0 { k = (k - 1) / 2 ; self . data [k] = (self . f) (self . data [k * 2 + 1] + self . lazy [k * 2 + 1] , self . data [k * 2 + 2] + self . lazy [k * 2 + 2] ,) ; } } else { let mid = (seg_range . start + seg_range . end) / 2 ; self . add_to_range (add_range . clone () , value , k * 2 + 1 , seg_range . start .. mid) ; self . add_to_range (add_range , value , k * 2 + 2 , mid .. seg_range . end) ; } } pub fn update (& mut self , pos : usize , value : T) { let cur = self . get (pos .. (pos + 1)) ; let mut k = pos + self . size - 1 ; let raw = self . data [k] ; self . data [k] = raw + value - cur ; while k > 0 { k = (k - 1) / 2 ; self . data [k] = (self . f) (self . data [k * 2 + 1] , self . data [k * 2 + 2]) ; } } pub fn get (& self , range : Range) -> T { self . get_from_range (range , 0 , 0 .. self . size) } fn get_from_range (& self , get_range : Range , k : usize , seg_range : Range) -> T { if get_range . end <= seg_range . start || seg_range . end <= get_range . start { self . init } else if get_range . start <= seg_range . start && seg_range . end <= get_range . end { self . data [k] + self . lazy [k] } else { let mid = (seg_range . start + seg_range . end) / 2 ; let x = self . get_from_range (get_range . clone () , k * 2 + 1 , seg_range . start .. mid) ; let y = self . get_from_range (get_range , k * 2 + 2 , mid .. seg_range . end) ; (self . f) (x , y) + self . lazy [k] } } } } # [cfg (test)] mod test { use super :: * ; use rand :: Rng ; use std :: cmp ; const INF : i64 = 1 << 60 ; # [test] fn edge_case () { let n = 5 ; let mut seg_min = range_add_segment_tree :: RangeAddSegmentTree :: new (n , INF as usize , | a , b | if a > b { b } else { a } , 0 ,) ; let mut values = vec ! [0 ; n] ; for i in 0 .. n { values [i] = i ; seg_min . update (i , i) ; } let from = 1 ; let to = 4 ; let add = 2 ; for i in from .. to { values [i] += add ; } seg_min . add (from .. to , add) ; let pos = 2 ; let value = 1 ; let cur = seg_min . get (pos .. (pos + 1)) ; seg_min . update (pos , cur - value) ; values [pos] -= value ; for l in 0 .. n { for r in (l + 1) .. (n + 1) { let min1 = seg_min . get (l .. r) ; let & min2 = values [l .. r] . iter () . min () . unwrap () ; assert_eq ! (min1 , min2) ; } } } # [test] fn random_add () { let n = 32 ; let mut array = vec ! [0 ; n] ; let mut seg_min = range_add_segment_tree :: RangeAddSegmentTree :: new (n , INF , | a , b | if a > b { b } else { a } , 0 ,) ; let mut seg_max = range_add_segment_tree :: RangeAddSegmentTree :: new (n , - INF , | a , b | if a < b { b } else { a } , 0 ,) ; for i in 0 .. n { let value = rand :: thread_rng () . gen :: < i16 > () as i64 ; array [i] = value ; seg_min . update (i , value) ; seg_max . update (i , value) ; } for l in 0 .. n { for r in (l + 1) .. n { let value = rand :: thread_rng () . gen :: < i16 > () as i64 ; seg_min . add (l .. r , value) ; seg_max . add (l .. r , value) ; for i in l .. r { array [i] += value ; } for l in 0 .. n { for r in (l + 1) .. n { let mut min = INF ; let mut max = - INF ; for i in l .. r { min = cmp :: min (min , array [i]) ; max = cmp :: max (max , array [i]) ; } assert_eq ! (seg_min . get (l .. r) , min) ; assert_eq ! (seg_max . get (l .. r) , max) ; } } } } } } } pub mod segment_tree { # [doc = " Segment Tree for range queries"] pub struct SegmentTree < T , F > { seg : Vec < T > , n : usize , f : F , initial_value : T , } impl < T : Copy , F > SegmentTree < T , F > where F : Fn (T , T) -> T , { pub fn new (size : usize , initial_value : T , f : F) -> SegmentTree < T , F > { let mut m = 1 ; while m <= size { m <<= 1 ; } SegmentTree { seg : vec ! [initial_value ; m * 2] , n : m , f , initial_value , } } pub fn update (& mut self , k : usize , value : T) { let mut k = k ; k += self . n - 1 ; self . seg [k] = value ; while k > 0 { k = (k - 1) >> 1 ; self . seg [k] = (self . f) (self . seg [k * 2 + 1] , self . seg [k * 2 + 2]) ; } } # [doc = " Get the minimum value in the array in the range"] pub fn query (& self , range : std :: ops :: Range < usize >) -> T { self . query_range (range , 0 , 0 .. self . n) } fn query_range (& self , range : std :: ops :: Range < usize > , k : usize , seg_range : std :: ops :: Range < usize > ,) -> T { if seg_range . end <= range . start || range . end <= seg_range . start { self . initial_value } else if range . start <= seg_range . start && seg_range . end <= range . end { self . seg [k] } else { let mid = (seg_range . start + seg_range . end) >> 1 ; let x = self . query_range (range . clone () , k * 2 + 1 , seg_range . start .. mid) ; let y = self . query_range (range , k * 2 + 2 , mid .. seg_range . end) ; (self . f) (x , y) } } } # [cfg (test)] mod test { use super :: * ; use rand :: Rng ; use std :: cmp ; use std :: i64 :: MAX ; # [test] fn random_array () { let n = 1000 ; let arr = (0 .. n) . map (| _ | { return rand :: thread_rng () . gen :: < i64 > () ; }) . collect :: < Vec < _ > > () ; let mut seg = SegmentTree :: new (n , MAX , | a , b | cmp :: min (a , b)) ; for i in 0 .. n { let mut minimum = MAX ; for j in 0 .. (i + 1) { minimum = cmp :: min (minimum , arr [j]) ; } seg . update (i , arr [i]) ; assert_eq ! (seg . query (0 .. n) , minimum) ; assert_eq ! (seg . query (0 .. (i + 1)) , minimum) ; } } # [test] fn random_array_online_update () { let n = 1000 ; let mut arr = vec ! [MAX ; n] ; let mut seg = SegmentTree :: new (n , MAX , | a , b | cmp :: min (a , b)) ; for _ in 0 .. n { let value = rand :: thread_rng () . gen :: < i64 > () ; let k = rand :: thread_rng () . gen_range (0 , n) ; seg . update (k , value) ; arr [k] = value ; let mut minimum = MAX ; for i in 0 .. n { minimum = cmp :: min (minimum , arr [i]) ; } assert_eq ! (seg . query (0 .. n) , minimum) ; } } } } pub mod sparse_table { pub mod sparse_table { pub struct SparseTable < T , F > { data : Vec < Vec < T > > , op : F , } impl < T , F > SparseTable < T , F > where T : Copy , F : Fn (T , T) -> T , { pub fn from (v : & [T] , init : T , op : F) -> Self { let size = v . len () . next_power_of_two () ; let count = size . trailing_zeros () as usize + 1 ; let mut data = vec ! [vec ! [init ; size] ; count] ; for (i , v) in v . iter () . cloned () . enumerate () { data [0] [i] = v ; } for c in 1 .. count { for i in 0 .. size { let next = std :: cmp :: min (size - 1 , i + (1 << (c - 1))) ; data [c] [i] = op (data [c - 1] [i] , data [c - 1] [next]) ; } } Self { data , op } } # [doc = " get the result for [l, r)"] pub fn get (& self , l : usize , r : usize) -> T { assert ! (l < r) ; let length = r - l ; if length == 1 { return self . data [0] [l] ; } let block_size = length . next_power_of_two () >> 1 ; let c = block_size . trailing_zeros () as usize ; let left = self . data [c] [l] ; let right = self . data [c] [r - block_size] ; (self . op) (left , right) } } } # [cfg (test)] mod test { use super :: * ; use rand :: { thread_rng , Rng } ; use std :: cmp ; # [test] fn test_small () { let v = vec ! [1 , 9 , 9 , 1 , 0 , 7 , 1 , 7] ; let sparse_table = sparse_table :: SparseTable :: from (& v , 0 , | a , b | cmp :: min (a , b)) ; for l in 0 .. 8 { for r in (l + 1) .. 9 { let & min = v [l .. r] . iter () . min () . unwrap () ; assert_eq ! (sparse_table . get (l , r) , min) ; } } } # [test] fn test_sparse_table_with_random_array () { let n = 1000 ; let v : Vec < u64 > = (0 .. n) . map (| _ | thread_rng () . gen_range (0 , 1000000000)) . collect () ; let sparse_table = sparse_table :: SparseTable :: from (& v , 0 , cmp :: min) ; for l in 0 .. n { for r in (l + 1) .. (n + 1) { let & min = v [l .. r] . iter () . min () . unwrap () ; assert_eq ! (sparse_table . get (l , r) , min) ; } } } } } pub mod suffix_array { pub struct SuffixArray { n : usize , s : Vec < u8 > , array : Vec < usize > , } fn compare_node (i : usize , j : usize , k : usize , rank : & [i32]) -> std :: cmp :: Ordering { if rank [i] != rank [j] { rank [i] . cmp (& rank [j]) } else { let ri = if i + k <= rank . len () { rank [i + k] } else { - 1 } ; let rj = if j + k <= rank . len () { rank [j + k] } else { - 1 } ; ri . cmp (& rj) } } impl SuffixArray { pub fn new (s : & [u8]) -> SuffixArray { let n = s . len () ; let mut rank = vec ! [0 ; n + 1] ; let mut array = vec ! [0 ; n + 1] ; for i in 0 .. (n + 1) { array [i] = i ; rank [i] = if i < n { s [i] as i32 } else { - 1 } ; } let mut tmp = vec ! [0 ; n + 1] ; let mut k = 1 ; while k <= n { array . sort_by (| a , b | compare_node (* a , * b , k , & rank)) ; tmp [array [0]] = 0 ; for i in 1 .. (n + 1) { tmp [array [i]] = tmp [array [i - 1]] + if compare_node (array [i - 1] , array [i] , k , & rank) == std :: cmp :: Ordering :: Less { 1 } else { 0 } } rank [.. (n + 1)] . clone_from_slice (& tmp [.. (n + 1)]) ; k *= 2 ; } SuffixArray { n , array , s : Vec :: from (s) , } } pub fn contains (& self , t : & [u8]) -> bool { let b = self . lower_bound (t) ; if b >= self . array . len () { false } else { let start = self . array [b] ; let end = std :: cmp :: min (t . len () + start , self . s . len ()) ; let sub = & self . s [start .. end] ; sub . cmp (t) == std :: cmp :: Ordering :: Equal } } fn binary_search < F > (& self , string : & [u8] , f : F) -> usize where F : Fn (& [u8] , & [u8]) -> bool , { let (mut ng , mut ok) = (- 1 , self . n as i32 + 1) ; while ok - ng > 1 { let pos = (ng + ok) / 2 ; let start = self . array [pos as usize] ; let end = std :: cmp :: min (start + string . len () , self . s . len ()) ; let substring = & self . s [start .. end] ; if f (substring , string) { ng = pos ; } else { ok = pos ; } } ok as usize } pub fn lower_bound (& self , t : & [u8]) -> usize { let check_function = | sub : & [u8] , s : & [u8] | sub . cmp (s) == std :: cmp :: Ordering :: Less ; self . binary_search (t , check_function) } pub fn upper_bound (& self , t : & [u8]) -> usize { let check_function = | sub : & [u8] , s : & [u8] | sub . cmp (s) != std :: cmp :: Ordering :: Greater ; self . binary_search (t , check_function) } } # [cfg (test)] mod test { use super :: * ; use crate :: data_structure :: segment_tree :: SegmentTree ; use crate :: utils :: test_helper :: Tester ; use std ; use std :: cmp ; # [test] fn small_test () { let string = "abcdeabcde" . to_owned () . bytes () . collect :: < Vec < _ > > () ; let sa = SuffixArray :: new (& string) ; assert_eq ! (sa . lower_bound (& "a" . to_owned () . bytes () . collect ::< Vec < _ >> ()) , 1) ; assert_eq ! (sa . upper_bound (& "a" . to_owned () . bytes () . collect ::< Vec < _ >> ()) , 3) ; assert ! (sa . contains (& "abcde" . to_owned () . bytes () . collect ::< Vec < _ >> ())) ; assert ! (! sa . contains (& "abce" . to_owned () . bytes () . collect ::< Vec < _ >> ())) ; } # [test] fn corner_case () { let string = "cba" . to_owned () . bytes () . collect :: < Vec < _ > > () ; let sa = SuffixArray :: new (& string) ; assert_eq ! (sa . lower_bound (& "c" . to_owned () . bytes () . collect ::< Vec < _ >> ()) , 3) ; assert_eq ! (sa . upper_bound (& "c" . to_owned () . bytes () . collect ::< Vec < _ >> ()) , 4) ; } # [test] fn jag2014summer_day4_f () { let tester = Tester :: new ("./assets/jag2014summer-day4/F/in/" , "./assets/jag2014summer-day4/F/out/" ,) ; tester . test_solution (| sc | { let s : Vec < u8 > = sc . read :: < String > () . bytes () . collect () ; let n = s . len () ; let reverse_s = { let mut r = s . clone () ; r . reverse () ; r } ; let sa = SuffixArray :: new (& s) ; let reverse_sa = SuffixArray :: new (& reverse_s) ; let mut rmq = SegmentTree :: new (n + 1 , std :: i64 :: MAX , | a , b | cmp :: min (a , b)) ; let mut reverse_rmq = SegmentTree :: new (n + 1 , std :: i64 :: MAX , | a , b | cmp :: min (a , b)) ; for i in 0 .. (n + 1) { rmq . update (i , sa . array [i] as i64) ; reverse_rmq . update (i , reverse_sa . array [i] as i64) ; } let m : usize = sc . read () ; for _ in 0 .. m { let x = sc . read :: < String > () . bytes () . collect :: < Vec < _ > > () ; let y = { let mut y : Vec < u8 > = sc . read :: < String > () . bytes () . collect :: < Vec < _ > > () ; y . reverse () ; y } ; if ! sa . contains (& x) { sc . write ("0\n") ; continue ; } let low = sa . lower_bound (& x) ; let up = sa . upper_bound (& x) ; if ! reverse_sa . contains (& y) { sc . write ("0\n") ; continue ; } let reverse_low = reverse_sa . lower_bound (& y) ; let reverse_up = reverse_sa . upper_bound (& y) ; if low >= up || reverse_low >= reverse_up { sc . write ("0\n") ; } let s = rmq . query (low .. up) as usize ; let t = n - reverse_rmq . query (reverse_low .. reverse_up) as usize ; if s + x . len () <= t && s <= t - y . len () { sc . write (format ! ("{}\n" , t - s)) ; } else { sc . write ("0\n") ; } } }) ; } } } pub mod treap { pub mod treap { use std :: cmp :: Ordering :: * ; type Link < T > = Option < Box < Node < T > > > ; # [derive (Debug)] struct Node < T > { left : Link < T > , right : Link < T > , key : T , priority : u32 , count : usize , } impl < T > Node < T > { fn new (key : T , priority : u32) -> Link < T > { Some (Box :: new (Node { left : None , right : None , key , priority , count : 1 , })) } fn update (& mut self) { self . count = 1 + count (& self . left) + count (& self . right) ; } } # [doc = " `Treap` is a binary search tree data structure that maintain a dynamic set"] # [doc = " of ordered keys and allow binary searches among the keys,"] # [doc = " [https://en.wikipedia.org/wiki/Treap](https://en.wikipedia.org/wiki/Treap)"] # [derive (Debug)] pub struct Treap < T > { random_state : XorShift , root : Link < T > , } impl < T : PartialOrd > Treap < T > where T : Clone , { pub fn new (seed : u32) -> Self { Treap { random_state : XorShift { state : seed } , root : None , } } pub fn clear (& mut self) { self . root = None } pub fn is_empty (& self) -> bool { count (& self . root) == 0 } pub fn insert (& mut self , key : T) { if ! self . contains (& key) { self . root = insert (self . root . take () , key , & mut self . random_state) ; } } pub fn contains (& self , key : & T) -> bool { find (& self . root , key) . is_some () } pub fn erase (& mut self , key : & T) { self . root = erase (self . root . take () , key) ; } pub fn nth (& self , n : usize) -> & T { match rank (& self . root , n) { Some (r) => & r . key , None => panic ! () , } } } fn find < T : PartialOrd > (node : & Link < T > , key : & T) -> Option < usize > { match node { None => None , Some (node) => match node . key . partial_cmp (key) . unwrap () { Equal => Some (count (& node . left)) , Greater => find (& node . left , key) , Less => match find (& node . right , key) { None => None , Some (pos) => Some (count (& node . left) + 1 + pos) , } , } , } } fn count < T > (node : & Link < T >) -> usize { match node { None => 0 , Some (node) => node . count , } } fn rotate_left < T > (node : Link < T >) -> Link < T > { let mut node = node . unwrap () ; let mut r = node . right . take () . unwrap () ; node . right = r . left . take () ; node . update () ; r . left = Some (node) ; Some (r) } fn rotate_right < T > (node : Link < T >) -> Link < T > { let mut node = node . unwrap () ; let mut l = node . left . take () . unwrap () ; node . left = l . right . take () ; node . update () ; l . right = Some (node) ; Some (l) } fn insert < T : PartialOrd > (node : Link < T > , key : T , rand : & mut XorShift) -> Link < T > { match node { None => Node :: new (key , rand . next ()) , Some (mut node) => { match node . key . partial_cmp (& key) . unwrap () { Less => { node . right = insert (node . right . take () , key , rand) ; if priority (& node . right) < node . priority { node = rotate_left (Some (node)) . unwrap () ; } } _ => { node . left = insert (node . left . take () , key , rand) ; if priority (& node . left) < node . priority { node = rotate_right (Some (node)) . unwrap () ; } } } node . update () ; Some (node) } } } fn priority < T > (node : & Link < T >) -> u32 { match * node { None => panic ! () , Some (ref node) => node . priority , } } fn min < T > (node : & Link < T >) -> & Link < T > { match node { Some (x) => match x . left { Some (_) => min (& x . left) , None => node , } , None => panic ! () , } } fn erase < T : PartialOrd > (node : Link < T > , key : & T) -> Link < T > where T : Clone , { match node { None => panic ! () , Some (mut node) => match node . key . partial_cmp (key) . unwrap () { Equal => { if node . left . is_none () { node . right } else if node . right . is_none () { node . left } else { node . key = match min (& node . right) { Some (m) => m . key . clone () , None => panic ! () , } ; node . right = erase (node . right . take () , & node . key) ; node . update () ; Some (node) } } Less => { node . right = erase (node . right . take () , key) ; node . update () ; Some (node) } Greater => { node . left = erase (node . left . take () , key) ; node . update () ; Some (node) } } , } } fn rank < T > (node : & Link < T > , r : usize) -> & Link < T > { match node { Some (c) => { let left = count (& c . left) ; match left . cmp (& r) { std :: cmp :: Ordering :: Equal => node , std :: cmp :: Ordering :: Less => rank (& c . right , r - left - 1) , std :: cmp :: Ordering :: Greater => rank (& c . left , r) , } } None => panic ! () , } } # [derive (Debug)] struct XorShift { state : u32 , } impl XorShift { fn next (& mut self) -> u32 { self . state = xor_shift (self . state) ; self . state } } fn xor_shift (state : u32) -> u32 { let mut x = state ; x ^= x << 13 ; x ^= x >> 17 ; x ^= x << 5 ; x } } # [cfg (test)] mod test { use super :: * ; # [test] fn test_treap_insert_erase () { let mut treap = treap :: Treap :: new (71) ; let max = 1000000 ; for i in 0 .. max { assert ! (! treap . contains (& i)) ; treap . insert (i) ; assert ! (treap . contains (& i)) ; } for i in 0 .. max { assert ! (treap . contains (& i)) ; treap . erase (& i) ; assert ! (! treap . contains (& i)) ; } } # [test] fn test_treap_nth () { let mut treap = treap :: Treap :: new (71) ; let max = 100000 ; for i in 0 .. max { treap . insert (i * 2) ; } for i in 0 .. max { assert_eq ! (treap . nth (i) , & (i * 2)) ; } } } } pub mod union_find { pub struct UnionFind { parent : Vec < usize > , sizes : Vec < usize > , size : usize , } impl UnionFind { pub fn new (n : usize) -> UnionFind { UnionFind { parent : (0 .. n) . map (| i | i) . collect :: < Vec < usize > > () , sizes : vec ! [1 ; n] , size : n , } } pub fn find (& mut self , x : usize) -> usize { if x == self . parent [x] { x } else { let px = self . parent [x] ; self . parent [x] = self . find (px) ; self . parent [x] } } pub fn unite (& mut self , x : usize , y : usize) -> bool { let parent_x = self . find (x) ; let parent_y = self . find (y) ; if parent_x == parent_y { return false ; } let (large , small) = if self . sizes [parent_x] < self . sizes [parent_y] { (parent_y , parent_x) } else { (parent_x , parent_y) } ; self . parent [small] = large ; self . sizes [large] += self . sizes [small] ; self . sizes [small] = 0 ; self . size -= 1 ; true } } # [cfg (test)] mod test { use super :: * ; use crate :: utils :: test_helper :: Tester ; # [doc = " Solve http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_1_A"] # [test] fn solve_dsl_1_a () { let tester = Tester :: new ("./assets/DSL_1_A/in/" , "./assets/DSL_1_A/out/") ; tester . test_solution (| sc | { let n = sc . read () ; let q = sc . read () ; let mut uf = UnionFind :: new (n) ; for _ in 0 .. q { let com : usize = sc . read () ; let x = sc . read () ; let y = sc . read () ; if com == 0 { uf . unite (x , y) ; } else { let ans = if uf . find (x) == uf . find (y) { 1 } else { 0 } ; sc . write (format ! ("{}\n" , ans)) ; } } }) ; } } } } # [doc = " Mathematical algorithms."] pub mod math { pub mod chinese_remainder_theorem { pub fn extended_gcd (a : i64 , b : i64 , p : & mut i64 , q : & mut i64) -> i64 { if b == 0 { * p = 1 ; * q = 0 ; a } else { let d = extended_gcd (b , a % b , q , p) ; * q -= a / b * * p ; d } } pub fn chinese_remainder_theorem (b : & [i64] , modulo : & [i64]) -> Option < (i64 , i64) > { let (mut result , mut m) = (0 , 1) ; for i in 0 .. b . len () { let (mut p , mut q) = (0 , 0) ; let d = extended_gcd (m , modulo [i] , & mut p , & mut q) ; if (b [i] - result) % d != 0 { return None ; } let tmp = ((b [i] - result) / d * p) % (modulo [i] / d) ; result += m * tmp ; m *= modulo [i] / d ; } Some (((result % m + m) % m , m)) } # [cfg (test)] mod tests { use super :: * ; use rand ; use rand :: Rng ; # [test] fn test_crt () { let mut rng = rand :: thread_rng () ; let n = 10 ; let max_m = 100 ; for _ in 0 .. 1000 { let ans = rng . gen :: < u32 > () as i64 ; let mut b = vec ! [0 ; n] ; let mut m = vec ! [0 ; n] ; for i in 0 .. n { m [i] = rng . gen :: < u8 > () as i64 ; m [i] %= max_m ; m [i] += 1 ; b [i] = ans % m [i] ; } let (a , _) = chinese_remainder_theorem (& b , & m) . unwrap () ; for i in 0 .. n { assert_eq ! (a % m [i] , b [i]) ; } } } } } pub mod combination { pub struct Combination { fact : Vec < usize > , inv_fact : Vec < usize > , modulo : usize , } impl Combination { pub fn new (max : usize , modulo : usize) -> Self { let mut inv = vec ! [0 ; max + 1] ; let mut fact = vec ! [0 ; max + 1] ; let mut inv_fact = vec ! [0 ; max + 1] ; inv [1] = 1 ; for i in 2 .. (max + 1) { inv [i] = inv [modulo % i] * (modulo - modulo / i) % modulo ; } fact [0] = 1 ; inv_fact [0] = 1 ; for i in 0 .. max { fact [i + 1] = fact [i] * (i + 1) % modulo ; } for i in 0 .. max { inv_fact [i + 1] = inv_fact [i] * inv [i + 1] % modulo ; } Self { fact , inv_fact , modulo , } } pub fn get (& self , x : usize , y : usize) -> usize { assert ! (x >= y) ; self . fact [x] * self . inv_fact [y] % self . modulo * self . inv_fact [x - y] % self . modulo } pub fn h (& self , n : usize , r : usize) -> usize { self . get (n + r - 1 , r) } } # [cfg (test)] mod test { use super :: * ; fn gcd (a : usize , b : usize) -> usize { if b == 0 { a } else { gcd (b , a % b) } } # [test] fn random_combination () { let modulo = 1_000_000_007 ; for n in 100 .. 200 { let comb = Combination :: new (n , modulo) ; for m in 0 .. (n + 1) { let mut upper = (0 .. m) . map (| i | n - i) . collect :: < Vec < _ > > () ; for i in 0 .. m { let mut divisor = i + 1 ; for j in 0 .. (i + 1) { if divisor == 1 { break ; } let g = gcd (divisor , upper [j]) ; upper [j] /= g ; divisor /= g ; } } let mut check = 1 ; for u in & upper { check = (check * u) % modulo ; } assert_eq ! (comb . get (n , m) , check) ; } } } } } pub mod cumulative_sum { pub struct CumulativeSum < T > (Vec < Vec < T > >) ; impl < T > CumulativeSum < T > where T : Copy + std :: ops :: Add < Output = T > + std :: ops :: Sub < Output = T > , { pub fn new (a : & [Vec < T >] , init : T) -> CumulativeSum < T > { assert ! (! a . is_empty ()) ; let h = a . len () ; let w = a [0] . len () ; let mut sum = vec ! [vec ! [init ; w + 1] ; h + 1] ; for i in 0 .. h { for j in 0 .. w { sum [i + 1] [j + 1] = a [i] [j] + sum [i] [j + 1] + sum [i + 1] [j] - sum [i] [j] ; } } CumulativeSum (sum) } pub fn get_sum (& self , h_range : std :: ops :: Range < usize > , w_range : std :: ops :: Range < usize >) -> T { assert ! (h_range . end <= self . 0 . len ()) ; assert ! (w_range . end <= self . 0 [0] . len ()) ; self . 0 [h_range . end] [w_range . end] + self . 0 [h_range . start] [w_range . start] - self . 0 [h_range . start] [w_range . end] - self . 0 [h_range . end] [w_range . start] } } # [cfg (test)] mod test { use super :: * ; use rand :: distributions :: Uniform ; use rand :: Rng ; # [test] fn random_array () { let h = 30 ; let w = 20 ; let mut rng = rand :: thread_rng () ; for _ in 0 .. 10 { let mut array = vec ! [vec ! [0 ; w] ; h] ; for i in 0 .. h { for j in 0 .. w { array [i] [j] = rng . sample (Uniform :: from (10 .. 10000)) ; } } let sum = CumulativeSum :: new (& array , 0) ; for from_i in 0 .. h { for to_i in (from_i + 1) ..= h { for from_j in 0 .. w { for to_j in (from_j + 1) ..= w { let mut check = 0 ; for i in from_i .. to_i { for j in from_j .. to_j { check += array [i] [j] ; } } assert_eq ! (check , sum . get_sum (from_i .. to_i , from_j .. to_j)) ; } } } } } } } } pub mod floor_sum { pub fn floor_sum (n : i64 , m : i64 , mut a : i64 , mut b : i64) -> i64 { let mut ans = 0 ; if a >= m { ans += (n - 1) * n * (a / m) / 2 ; a %= m ; } if b >= m { ans += n * (b / m) ; b %= m ; } let y_max = (a * n + b) / m ; let x_max = y_max * m - b ; if y_max == 0 { ans } else { ans += (n - (x_max + a - 1) / a) * y_max ; ans += floor_sum (y_max , a , m , (a - x_max % a) % a) ; ans } } # [cfg (test)] mod tests { use super :: * ; # [test] fn test_floor_sum () { assert_eq ! (3 , floor_sum (4 , 10 , 6 , 3)) ; assert_eq ! (13 , floor_sum (6 , 5 , 4 , 3)) ; assert_eq ! (0 , floor_sum (1 , 1 , 0 , 0)) ; assert_eq ! (314095480 , floor_sum (31415 , 92653 , 58979 , 32384)) ; assert_eq ! (499999999500000000 , floor_sum (1000000000 , 1000000000 , 999999999 , 999999999)) ; } } } pub mod lagrange_interpolation { pub fn lagrange_interpolation < T > (xs : & [T] , ys : & [T] , one : T , zero : T) -> Vec < T > where T : Clone + Copy + std :: ops :: Sub < Output = T > + std :: ops :: Mul < Output = T > + std :: ops :: Div < Output = T > + std :: ops :: AddAssign + std :: ops :: SubAssign + std :: ops :: MulAssign , { let n = xs . len () ; let mut all_c = vec ! [zero ; n + 1] ; all_c [0] = one ; for & x in xs . iter () { let mut next = vec ! [zero ; n + 1] ; next [1 .. (n + 1)] . clone_from_slice (& all_c [.. n]) ; for j in 0 .. n { next [j] -= x * all_c [j] ; } all_c = next ; } let mut c = vec ! [zero ; n] ; for i in 0 .. n { let mut qi = one ; for j in 0 .. n { if i == j { continue ; } qi *= xs [i] - xs [j] ; } let ri = ys [i] / qi ; let mut tmp_c = all_c . clone () ; for j in (0 .. n) . rev () { c [j] += ri * tmp_c [j + 1] ; let next_c = tmp_c [j + 1] * xs [i] ; tmp_c [j] += next_c ; } } c } # [cfg (test)] mod tests { use super :: * ; use crate :: math :: mod_int :: mod_int :: ModInt ; use rand :: { thread_rng , Rng } ; const MOD : u64 = 1e9 as u64 + 7 ; # [test] fn test_lagrange_interpolation () { let mut rng = thread_rng () ; let n = 500 ; for _ in 0 .. 10 { let mut xs = vec ! [] ; let mut ys = vec ! [] ; for _ in 0 .. n { xs . push (ModInt :: new (rng . gen () , MOD)) ; ys . push (ModInt :: new (rng . gen () , MOD)) ; } let c = lagrange_interpolation (& xs , & ys , ModInt :: new (1 , MOD) , ModInt :: new (0 , MOD)) ; for i in 0 .. n { let mut y = ModInt :: new (0 , MOD) ; let x = xs [i] ; for i in 0 .. n { y += x . pow (i as u64) * c [i] ; } assert_eq ! (y . value () , ys [i] . value ()) ; } } } } } pub mod max_rectangle { pub mod max_rectangle { use std :: cmp ; use std :: collections :: VecDeque ; fn calc (hist : & [usize]) -> usize { let n = hist . len () ; let mut ans = 0 ; let mut q : VecDeque < (usize , usize) > = VecDeque :: new () ; for (i , & hist) in hist . iter () . enumerate () { let mut reachable_min = i ; while let Some ((pos , height)) = q . pop_front () { if height <= hist { q . push_front ((pos , height)) ; break ; } reachable_min = pos ; ans = cmp :: max (ans , (i - reachable_min) * height) ; } if q . is_empty () || q . iter () . next () . unwrap () . 1 < hist { q . push_front ((reachable_min , hist)) ; } } while let Some ((pos , height)) = q . pop_front () { ans = cmp :: max (ans , (n - pos) * height) ; } ans } pub fn maximize (map : & [Vec < bool >]) -> usize { let h = map . len () ; let w = map [0] . len () ; let mut hist = vec ! [vec ! [0 ; w] ; h] ; for i in 0 .. h { for j in 0 .. w { if ! map [i] [j] { continue ; } if i == 0 { hist [i] [j] = 1 ; } else { hist [i] [j] = hist [i - 1] [j] + 1 ; } } } let mut ans = 0 ; for hist in hist . iter () { ans = cmp :: max (ans , calc (hist)) ; } ans } } # [cfg (test)] mod test { use super :: * ; use crate :: utils :: test_helper :: Tester ; # [test] fn solve_dpl_3_b () { let tester = Tester :: new ("./assets/DPL_3_B/in/" , "./assets/DPL_3_B/out/") ; tester . test_solution (| sc | { let h : usize = sc . read () ; let w : usize = sc . read () ; let mut c = vec ! [vec ! [false ; w] ; h] ; for i in 0 .. h { for j in 0 .. w { c [i] [j] = sc . read :: < usize > () == 0 ; } } let ans = max_rectangle :: maximize (& c) ; sc . write (format ! ("{}\n" , ans)) ; }) ; } } } pub mod mod_int { pub mod mod_int { use std :: ops :: { Add , AddAssign , BitAnd , Div , DivAssign , Mul , MulAssign , RemAssign , ShrAssign , Sub , SubAssign , } ; pub struct ModInt < T > { v : T , m : T , } impl < T > ModInt < T > where T : Copy , { pub fn value (& self) -> T { self . v } pub fn modulo (& self) -> T { self . m } } impl < T > ModInt < T > { fn new_unchecked (v : T , modulo : T) -> Self { Self { v , m : modulo } } } impl < T > ModInt < T > where T : Copy + RemAssign + PartialOrd , { pub fn new (mut v : T , modulo : T) -> Self { if v >= modulo { v %= modulo ; } Self :: new_unchecked (v , modulo) } } impl < T > ModInt < T > where T : Copy + Sub < Output = T > + ShrAssign + BitAnd < Output = T > + PartialEq + PartialOrd + Div < Output = T > + RemAssign , ModInt < T > : MulAssign , { pub fn pow (self , e : T) -> Self { let zero = self . modulo () - self . modulo () ; let one = self . modulo () / self . modulo () ; let mut e = e ; let mut result = Self :: new_unchecked (one , self . modulo ()) ; let mut cur = self ; while e > zero { if e & one == one { result *= cur ; } e >>= one ; cur *= cur ; } result } } impl < T > Copy for ModInt < T > where T : Copy { } impl < T > Clone for ModInt < T > where T : Copy , { fn clone (& self) -> Self { Self :: new_unchecked (self . value () , self . modulo ()) } } impl < T > Add < T > for ModInt < T > where T : AddAssign + SubAssign + RemAssign + Copy + PartialOrd , { type Output = Self ; fn add (self , mut rhs : T) -> Self :: Output { if rhs >= self . modulo () { rhs %= self . modulo () ; } rhs += self . value () ; if rhs >= self . modulo () { rhs -= self . modulo () ; } Self :: new_unchecked (rhs , self . modulo ()) } } impl < T > Sub < T > for ModInt < T > where T : AddAssign + SubAssign + RemAssign + Copy + PartialOrd , { type Output = Self ; fn sub (self , mut rhs : T) -> Self :: Output { if rhs >= self . modulo () { rhs %= self . modulo () ; } let mut result = self . value () ; result += self . modulo () ; result -= rhs ; if result >= self . modulo () { result -= self . modulo () ; } Self :: new_unchecked (result , self . modulo ()) } } impl < T > Mul < T > for ModInt < T > where T : MulAssign + RemAssign + Copy + PartialOrd , { type Output = Self ; fn mul (self , mut rhs : T) -> Self :: Output { if rhs >= self . modulo () { rhs %= self . modulo () ; } rhs *= self . value () ; rhs %= self . modulo () ; Self :: new_unchecked (rhs , self . modulo ()) } } impl < T > Add < ModInt < T > > for ModInt < T > where T : Copy , ModInt < T > : Add < T , Output = ModInt < T > > , { type Output = Self ; fn add (self , rhs : ModInt < T >) -> Self :: Output { self + rhs . value () } } impl < T > Sub < ModInt < T > > for ModInt < T > where T : Copy , ModInt < T > : Sub < T , Output = ModInt < T > > , { type Output = Self ; fn sub (self , rhs : ModInt < T >) -> Self :: Output { self - rhs . value () } } impl < T > Mul < ModInt < T > > for ModInt < T > where T : Copy , ModInt < T > : Mul < T , Output = ModInt < T > > , { type Output = Self ; fn mul (self , rhs : ModInt < T >) -> Self :: Output { self * rhs . value () } } impl < T > Div < ModInt < T > > for ModInt < T > where T : Copy , ModInt < T > : Div < T , Output = ModInt < T > > , { type Output = Self ; fn div (self , rhs : ModInt < T >) -> Self :: Output { self / rhs . value () } } impl < T > AddAssign < T > for ModInt < T > where T : Copy , ModInt < T > : Add < T , Output = ModInt < T > > , { fn add_assign (& mut self , other : T) { * self = * self + other ; } } impl < T > AddAssign < ModInt < T > > for ModInt < T > where T : Copy , ModInt < T > : Add < ModInt < T > , Output = ModInt < T > > , { fn add_assign (& mut self , other : ModInt < T >) { * self = * self + other ; } } impl < T > SubAssign < T > for ModInt < T > where T : Copy , ModInt < T > : Sub < T , Output = ModInt < T > > , { fn sub_assign (& mut self , other : T) { * self = * self - other ; } } impl < T > SubAssign < ModInt < T > > for ModInt < T > where T : Copy , ModInt < T > : Sub < ModInt < T > , Output = ModInt < T > > , { fn sub_assign (& mut self , other : ModInt < T >) { * self = * self - other ; } } impl < T > DivAssign < T > for ModInt < T > where T : Copy , ModInt < T > : Div < T , Output = ModInt < T > > , { fn div_assign (& mut self , rhs : T) { * self = * self / rhs } } impl < T > DivAssign < ModInt < T > > for ModInt < T > where T : Copy , ModInt < T > : Div < ModInt < T > , Output = ModInt < T > > , { fn div_assign (& mut self , rhs : ModInt < T >) { * self = * self / rhs } } impl < T > MulAssign < T > for ModInt < T > where T : Copy , ModInt < T > : Mul < T , Output = ModInt < T > > , { fn mul_assign (& mut self , rhs : T) { * self = * self * rhs ; } } impl < T > MulAssign < ModInt < T > > for ModInt < T > where T : Copy , ModInt < T > : Mul < ModInt < T > , Output = ModInt < T > > , { fn mul_assign (& mut self , rhs : ModInt < T >) { * self = * self * rhs ; } } impl < T > Div < T > for ModInt < T > where T : Copy + Add < Output = T > + Sub < Output = T > + Div < Output = T > + BitAnd < Output = T > + PartialEq + PartialOrd + ShrAssign + RemAssign + MulAssign , { type Output = Self ; fn div (self , mut rhs : T) -> Self :: Output { if rhs >= self . modulo () { rhs %= self . modulo () ; } let one = self . modulo () / self . modulo () ; let two = one + one ; self * Self :: new_unchecked (rhs , self . modulo ()) . pow (self . modulo () - two) } } } # [cfg (test)] mod test { use super :: mod_int :: * ; use rand :: distributions :: Uniform ; use rand :: Rng ; const MOD : u64 = 1_000_000_007 ; # [test] fn random_add_sub () { let mut rng = rand :: thread_rng () ; for _ in 0 .. 1000 { let x : u64 = rng . sample (Uniform :: from (0 .. MOD)) ; let y : u64 = rng . sample (Uniform :: from (0 .. MOD)) ; let mx = ModInt :: new (x , MOD) ; let my = ModInt :: new (y , MOD) ; assert_eq ! ((mx + my) . value () , (x + y) % MOD) ; assert_eq ! ((mx + y) . value () , (x + y) % MOD) ; assert_eq ! ((mx - my) . value () , (x + MOD - y) % MOD) ; assert_eq ! ((mx - y) . value () , (x + MOD - y) % MOD) ; let mut x = x ; let mut mx = mx ; x += y ; mx += my ; assert_eq ! (mx . value () , x % MOD) ; mx += y ; x += y ; assert_eq ! (mx . value () , x % MOD) ; mx -= my ; x = (x + MOD - y % MOD) % MOD ; assert_eq ! (mx . value () , x) ; mx -= y ; x = (x + MOD - y % MOD) % MOD ; assert_eq ! (mx . value () , x) ; } } # [test] fn random_mul () { let mut rng = rand :: thread_rng () ; for _ in 0 .. 1000 { let x : u64 = rng . sample (Uniform :: from (0 .. MOD)) ; let y : u64 = rng . sample (Uniform :: from (0 .. MOD)) ; let mx = ModInt :: new (x , MOD) ; let my = ModInt :: new (y , MOD) ; assert_eq ! ((mx * my) . value () , (x * y) % MOD) ; assert_eq ! ((mx * y) . value () , (x * y) % MOD) ; } } # [test] fn zero_test () { let a = ModInt :: new (1_000_000_000 , MOD) ; let b = ModInt :: new (7 , MOD) ; let c = a + b ; assert_eq ! (c . value () , 0) ; } # [test] fn pow_test () { let a = ModInt :: new (3 , MOD) ; let a = a . pow (4) ; assert_eq ! (a . value () , 81) ; } # [test] fn div_test () { for i in 1 .. 100000 { let mut a = ModInt :: new (1 , MOD) ; a /= i ; a *= i ; assert_eq ! (a . value () , 1) ; } } # [test] fn edge_cases () { let a = ModInt :: new (1_000_000_000 , MOD) * std :: u64 :: MAX ; assert_eq ! (a . value () , 923591986) ; let mut a = ModInt :: new (1_000_000_000 , MOD) ; a *= std :: u64 :: MAX ; assert_eq ! (a . value () , 923591986) ; let a = ModInt :: new (1_000_000_000 , MOD) + std :: u64 :: MAX ; assert_eq ! (a . value () , 582344000) ; let mut a = ModInt :: new (1_000_000_000 , MOD) ; a += std :: u64 :: MAX ; assert_eq ! (a . value () , 582344000) ; let a = ModInt :: new (1_000_000_000 , MOD) - std :: u64 :: MAX ; assert_eq ! (a . value () , 417655993) ; let mut a = ModInt :: new (1_000_000_000 , MOD) ; a -= std :: u64 :: MAX ; assert_eq ! (a . value () , 417655993) ; let a = ModInt :: new (1_000_000_000 , MOD) / std :: u64 :: MAX ; assert_eq ! (a . value () , 605455209) ; let mut a = ModInt :: new (1_000_000_000 , MOD) ; a /= std :: u64 :: MAX ; assert_eq ! (a . value () , 605455209) ; } # [test] fn overflow_guard () { let a = ModInt :: new (MOD * 10 , MOD) ; assert_eq ! (a . value () , 0) ; } } } pub mod next_permutation { pub trait NextPermutation { fn next_permutation (& mut self) -> bool ; } impl < T > NextPermutation for [T] where T : PartialOrd , { fn next_permutation (& mut self) -> bool { if self . len () < 2 { return false ; } let mut i = self . len () - 1 ; while i > 0 && self [i - 1] >= self [i] { i -= 1 ; } if i == 0 { return false ; } let mut j = self . len () - 1 ; while j >= i && self [j] <= self [i - 1] { j -= 1 ; } self . swap (j , i - 1) ; self [i ..] . reverse () ; true } } # [cfg (test)] mod tests { use super :: NextPermutation ; use std :: collections :: BTreeSet ; # [test] fn test_next_permutation () { let mut x = vec ! [1 , 2 , 3 , 4 , 5] ; let mut set = BTreeSet :: new () ; let mut count = 0 ; while x . next_permutation () { count += 1 ; set . insert (x . clone ()) ; } assert_eq ! (count + 1 , 5 * 4 * 3 * 2) ; assert_eq ! (set . len () , count) ; } } } } # [doc = " Geometry algorithms."] pub mod geometry { pub mod circle { pub fn cc_intersect ((p1 , r1) : (Point , f64) , (p2 , r2) : (Point , f64)) -> Vec < Point > { let dist = (p1 - p2) . abs () ; if dist > r1 + r2 { return Vec :: new () ; } let rc = (dist * dist + r1 * r1 - r2 * r2) / (2. * dist) ; let rs = (r1 * r1 - rc * rc) . sqrt () ; let diff = (p2 - p1) / dist ; vec ! [p1 + diff * Point (rc , rs) , p1 + diff * Point (rc , - rs)] } # [derive (Copy , Clone)] pub struct Point (f64 , f64) ; impl Point { fn abs (self) -> f64 { let x = self . 0 ; let y = self . 1 ; (x * x + y * y) . sqrt () } } impl :: std :: ops :: Add < Point > for Point { type Output = Point ; fn add (self , rhs : Point) -> Point { Point (self . 0 + rhs . 0 , self . 1 + rhs . 1) } } impl :: std :: ops :: Sub < Point > for Point { type Output = Point ; fn sub (self , rhs : Point) -> Point { Point (self . 0 - rhs . 0 , self . 1 - rhs . 1) } } impl :: std :: ops :: Div < f64 > for Point { type Output = Point ; fn div (self , rhs : f64) -> Point { Point (self . 0 / rhs , self . 1 / rhs) } } impl :: std :: ops :: Mul < Point > for Point { type Output = Point ; fn mul (self , rhs : Point) -> Point { let Point (x1 , y1) = self ; let Point (x2 , y2) = rhs ; Point (x1 * x2 - y1 * y2 , x1 * y2 + y1 * x2) } } # [cfg (test)] mod tests { use super :: * ; use crate :: utils :: test_helper :: Tester ; # [test] fn solve_cgl_7_e () { let tester = Tester :: new ("./assets/CGL_7_E/in/" , "./assets/CGL_7_E/out/") ; tester . test_solution_with (| sc | { let c1 = (Point (sc . read () , sc . read ()) , sc . read ()) ; let c2 = (Point (sc . read () , sc . read ()) , sc . read ()) ; let mut points = cc_intersect (c1 , c2) . into_iter () . map (| Point (x , y) | (x , y)) . collect :: < Vec < _ > > () ; if points [0] > points [1] { points . swap (0 , 1) ; } sc . write (format ! ("{} {} {} {}\n" , points [0] . 0 , points [0] . 1 , points [1] . 0 , points [1] . 1)) ; } , | expected , actual | { assert ! ((expected . read ::< f64 > () - actual . read ::< f64 > ()) . abs () < 1e-6) ; assert ! ((expected . read ::< f64 > () - actual . read ::< f64 > ()) . abs () < 1e-6) ; assert ! ((expected . read ::< f64 > () - actual . read ::< f64 > ()) . abs () < 1e-6) ; assert ! ((expected . read ::< f64 > () - actual . read ::< f64 > ()) . abs () < 1e-6) ; } ,) ; } } } pub mod convex_hull { pub fn extract_convex_hull (points : & [Point] , contain_on_segment : bool) -> Vec < usize > { let n = points . len () ; if n <= 1 { return vec ! [0] ; } let mut ps : Vec < usize > = (0 .. n) . collect () ; ps . sort_by (| & a , & b | { if (points [a] . x - points [b] . x) . abs () < std :: f64 :: EPSILON { points [a] . y . partial_cmp (& points [b] . y) . unwrap () } else { points [a] . x . partial_cmp (& points [b] . x) . unwrap () } }) ; let mut qs : Vec < usize > = Vec :: new () ; for & i in & ps { while qs . len () > 1 { let k = qs . len () ; let det = (points [qs [k - 1]] - points [qs [k - 2]]) . det (& (points [i] - points [qs [k - 1]])) ; if det < 0.0 || (det <= 0.0 && ! contain_on_segment) { qs . pop () ; } else { break ; } } qs . push (i) ; } let t = qs . len () ; for i in (0 .. (n - 1)) . rev () { let i = ps [i] ; while qs . len () > t { let k = qs . len () ; let det = (points [qs [k - 1]] - points [qs [k - 2]]) . det (& (points [i] - points [qs [k - 1]])) ; if det < 0.0 || (det <= 0.0 && ! contain_on_segment) { qs . pop () ; } else { break ; } } qs . push (i) ; } qs . pop () ; qs } # [derive (Debug , Copy , Clone)] pub struct Point { x : f64 , y : f64 , } impl std :: ops :: Sub for Point { type Output = Point ; fn sub (self , other : Point) -> Point { Point { x : self . x - other . x , y : self . y - other . y , } } } impl Point { pub fn det (& self , other : & Point) -> f64 { self . x * other . y - self . y * other . x } } # [cfg (test)] mod test { use super :: * ; use crate :: utils :: test_helper :: Tester ; # [doc = " Solve http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_A"] # [test] fn solve_cgl_4_a () { let tester = Tester :: new ("./assets/CGL_4_A/in/" , "./assets/CGL_4_A/out/") ; tester . test_solution (| sc | { let n : usize = sc . read () ; let mut points = Vec :: new () ; for _ in 0 .. n { let x : f64 = sc . read () ; let y : f64 = sc . read () ; points . push (Point { x , y }) ; } let convex_hull = extract_convex_hull (& points , true) ; sc . write (format ! ("{}\n" , convex_hull . len ())) ; let n = convex_hull . len () ; let mut start = 0 ; for i in 0 .. n { if points [convex_hull [i]] . y < points [convex_hull [start]] . y || (points [convex_hull [i]] . y == points [convex_hull [start]] . y && points [convex_hull [i]] . x < points [convex_hull [start]] . x) { start = i ; } } for i in 0 .. n { let i = (i + start) % n ; let i = convex_hull [i] ; sc . write (format ! ("{} {}\n" , points [i] . x , points [i] . y)) ; } }) ; } } } pub mod minimum_bounding_circle { pub mod minimum_bounding_circle { pub fn make_circle (ps : & [Point < f64 >]) -> (Point < f64 > , f64) { let n = ps . len () ; assert ! (n >= 2) ; let mut c = make_circle2 (ps [0] , ps [1]) ; for i in 2 .. n { if is_included (ps [i] , c) { continue ; } c = make_circle2 (ps [0] , ps [i]) ; for j in 1 .. i { if is_included (ps [j] , c) { continue ; } c = make_circle2 (ps [i] , ps [j]) ; for k in 0 .. j { if is_included (ps [k] , c) { continue ; } c = make_circle3 (ps [i] , ps [j] , ps [k]) ; } } } c } fn make_circle3 (a : Point < f64 > , b : Point < f64 > , c : Point < f64 >) -> (Point < f64 > , f64) { let ea = (b - c) . norm () ; let eb = (c - a) . norm () ; let ec = (a - b) . norm () ; let s = (b - a) . det (& (c - a)) ; let center = (a * ea * (eb + ec - ea) + b * eb * (ec + ea - eb) + c * ec * (ea + eb - ec)) / (s * s * 4.0) ; let r2 = (center - a) . norm () ; (center , r2) } fn make_circle2 (a : Point < f64 > , b : Point < f64 >) -> (Point < f64 > , f64) { let c = (a + b) / 2.0 ; let r2 = (a - c) . norm () ; (c , r2) } fn is_included (a : Point < f64 > , circle : (Point < f64 > , f64)) -> bool { let (center , r2) = circle ; (a - center) . norm () <= r2 } pub struct Point < T > { pub x : T , pub y : T , } impl < T > Copy for Point < T > where T : Copy { } impl < T > Clone for Point < T > where T : Clone , { fn clone (& self) -> Point < T > { Point { x : self . x . clone () , y : self . y . clone () , } } } impl < T > std :: ops :: Sub for Point < T > where T : std :: ops :: Sub < Output = T > , { type Output = Point < T > ; fn sub (self , other : Point < T >) -> Point < T > { Point { x : self . x - other . x , y : self . y - other . y , } } } impl < T > std :: ops :: Mul < T > for Point < T > where T : Copy + std :: ops :: Mul < Output = T > , { type Output = Point < T > ; fn mul (self , rhs : T) -> Point < T > { Point { x : self . x * rhs , y : self . y * rhs , } } } impl < T > std :: ops :: Div < T > for Point < T > where T : Copy + std :: ops :: Div < Output = T > , { type Output = Point < T > ; fn div (self , rhs : T) -> Point < T > { Point { x : self . x / rhs , y : self . y / rhs , } } } impl < T > std :: ops :: Add < Point < T > > for Point < T > where T : std :: ops :: Add < Output = T > , { type Output = Point < T > ; fn add (self , rhs : Point < T >) -> Point < T > { Point { x : self . x + rhs . x , y : self . y + rhs . y , } } } impl < T > Point < T > where T : Copy + std :: ops :: Mul < Output = T > + std :: ops :: Sub < Output = T > + std :: ops :: Add < Output = T > , { pub fn det (& self , other : & Point < T >) -> T { self . x * other . y - self . y * other . x } pub fn norm (& self) -> T { self . x * self . x + self . y * self . y } } } # [cfg (test)] mod tests { use super :: minimum_bounding_circle :: * ; use crate :: utils :: test_helper :: Tester ; # [test] fn solve_aoj2423 () { let tester = Tester :: new ("./assets/AOJ2423/in/" , "./assets/AOJ2423/out/") ; tester . test_solution (| sc | { let circles : usize = sc . read () ; let people : usize = sc . read () ; let rs : Vec < f64 > = sc . vec (circles) ; let mut people_r2 = vec ! [0.0 ; people] ; let mut people_list = vec ! [] ; for i in 0 .. people { let n : usize = sc . read () ; let mut ps = vec ! [] ; for _ in 0 .. n { let x : f64 = sc . read () ; let y : f64 = sc . read () ; ps . push (Point { x , y }) ; } let (_ , r2) = make_circle (& ps) ; people_list . push ((r2 , i)) ; people_r2 [i] = r2 ; } let mut circle_list = rs . iter () . enumerate () . map (| (i , & r) | (r , i)) . collect :: < Vec < _ > > () ; circle_list . sort_by (| a , b | a . 0 . partial_cmp (& b . 0) . unwrap ()) ; people_list . sort_by (| a , b | a . 0 . partial_cmp (& b . 0) . unwrap ()) ; let mut ans = vec ! [0 ; people] ; for _ in 0 .. people { let mut circle_buf = 0 ; let mut people_buf = people_list . len () ; for p_pos in (0 .. people_list . len ()) . rev () { for c_pos in (0 .. (circle_list . len () - circle_buf)) . rev () { if circle_list [c_pos] . 0 * circle_list [c_pos] . 0 >= people_list [p_pos] . 0 { circle_buf += 1 ; } else { break ; } } if people_list . len () - p_pos > circle_buf { sc . write ("NG\n") ; return ; } else if people_list . len () - p_pos == circle_buf { people_buf = people_list . len () - p_pos ; break ; } } let youngest_people = people_list . iter () . rev () . take (people_buf) . map (| p | p . 1) . min () . unwrap () ; let youngest_circle = circle_list . iter () . rev () . take (circle_buf) . map (| c | c . 1) . filter (| & i | rs [i] * rs [i] >= people_r2 [youngest_people]) . min () . unwrap () ; ans [youngest_people] = youngest_circle ; people_list = people_list . into_iter () . filter (| p | p . 1 != youngest_people) . collect :: < Vec < _ > > () ; circle_list = circle_list . into_iter () . filter (| c | c . 1 != youngest_circle) . collect :: < Vec < _ > > () ; } for i in ans . into_iter () { sc . write (format ! ("{}\n" , i + 1)) ; } }) ; } } } } # [doc = " Utilities for tests, stdin, and so on."] pub mod utils { # [doc = " Functions to test this library with contest-style IO files."] # [cfg (test)] pub (crate) mod test_helper { use crate :: utils :: scanner :: IO ; use std :: fs ; use std :: fs :: File ; use std :: io :: Read ; use std :: str ; pub (crate) struct Tester { input : Vec < (String , Vec < u8 >) > , output : Vec < (String , Vec < u8 >) > , } impl Tester { pub (crate) fn new (input_directory : & str , output_directory : & str) -> Tester { let input = read_from_directory (input_directory) ; let output = read_from_directory (output_directory) ; Tester { input , output } } pub (crate) fn test_solution < F > (self , solution : F) where F : Fn (& mut IO < & [u8] , & mut Vec < u8 > >) , { for ((input_label , input) , (output_label , output)) in self . input . into_iter () . zip (self . output) { eprintln ! ("Testing {} {}" , input_label , output_label) ; let mut writer = vec ! [] ; { let mut sc = IO :: new (& input [..] , & mut writer) ; solution (& mut sc) ; } assert_eq ! (writer , output) ; } } pub (crate) fn test_solution_with < F1 , F2 > (self , solution : F1 , assertion : F2) where F1 : Fn (& mut IO < & [u8] , & mut Vec < u8 > >) , F2 : Fn (& mut IO < & [u8] , & mut Vec < u8 > > , & mut IO < & [u8] , & mut Vec < u8 > >) , { for ((input_label , input) , (output_label , output)) in self . input . into_iter () . zip (self . output) { eprintln ! ("Testing {} {}" , input_label , output_label) ; let mut writer = vec ! [] ; { let mut sc = IO :: new (& input [..] , & mut writer) ; solution (& mut sc) ; } let mut actual_writer = vec ! [] ; let mut expected_writer = vec ! [] ; let mut actual = IO :: new (& writer [..] , & mut actual_writer) ; let mut expected = IO :: new (& output [..] , & mut expected_writer) ; assertion (& mut expected , & mut actual) ; } } } fn read_file (filepath : & str) -> Vec < u8 > { let mut file = File :: open (filepath) . unwrap () ; let mut buf = Vec :: new () ; file . read_to_end (& mut buf) . unwrap () ; buf } fn read_from_directory (directory_path : & str) -> Vec < (String , Vec < u8 >) > { let mut filenames : Vec < String > = fs :: read_dir (directory_path) . unwrap () . map (| result | result . unwrap () . path () . display () . to_string ()) . collect () ; filenames . sort () ; filenames . into_iter () . map (| file | { let data = read_file (& file) ; (file , data) }) . collect () } } pub mod scanner { pub struct IO < R , W : std :: io :: Write > (R , std :: io :: BufWriter < W >) ; impl < R : std :: io :: Read , W : std :: io :: Write > IO < R , W > { pub fn new (r : R , w : W) -> IO < R , W > { IO (r , std :: io :: BufWriter :: new (w)) } pub fn write < S : ToString > (& mut self , s : S) { use std :: io :: Write ; self . 1 . write_all (s . to_string () . as_bytes ()) . unwrap () ; } pub fn read < T : std :: str :: FromStr > (& mut self) -> T { use std :: io :: Read ; let buf = self . 0 . by_ref () . bytes () . map (| b | b . unwrap ()) . skip_while (| & b | b == b' ' || b == b'\n' || b == b'\r' || b == b'\t') . take_while (| & b | b != b' ' && b != b'\n' && b != b'\r' && b != b'\t') . collect :: < Vec < _ > > () ; unsafe { std :: str :: from_utf8_unchecked (& buf) } . parse () . ok () . expect ("Parse error.") } pub fn vec < T : std :: str :: FromStr > (& mut self , n : usize) -> Vec < T > { (0 .. n) . map (| _ | self . read ()) . collect () } pub fn chars (& mut self) -> Vec < char > { self . read :: < String > () . chars () . collect () } } # [cfg (test)] mod tests { use super :: * ; # [test] fn test_io () { let input = br"10
        1 2 3 4 5 6 7 8 9 10
        abcde fghij
        
        3.14 -1592
        no_empty_line" ; let mut sc = IO :: new (& input [..] , Vec :: new ()) ; let n : usize = sc . read () ; assert_eq ! (n , 10) ; let a : Vec < u64 > = sc . vec (n) ; assert_eq ! (& a , & [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10]) ; let s = sc . chars () ; let t = sc . chars () ; assert_eq ! (& s , & ['a' , 'b' , 'c' , 'd' , 'e']) ; assert_eq ! (& t , & ['f' , 'g' , 'h' , 'i' , 'j']) ; let f : f64 = sc . read () ; assert_eq ! (f , 3.14) ; let neg : i64 = sc . read () ; assert_eq ! (neg , - 1592) ; let s = sc . read :: < String > () ; assert_eq ! (& s , "no_empty_line") ; sc . write (format ! ("1\n")) ; let mut output = Vec :: new () ; { let mut sc = IO :: new (& b"" [..] , & mut output) ; sc . write (format ! ("{}\n" , 1)) ; sc . write (format ! ("{}\n" , 2)) ; sc . write (format ! ("{}\n" , 3)) ; } let output = String :: from_utf8 (output) . expect ("Not UTF-8") ; assert_eq ! (& output , "1\n2\n3\n") ; } } } } # [doc = " String algorithms."] pub mod string { pub mod rolling_hash { pub mod rolling_hash { const MASK_30 : u64 = (1 << 30) - 1 ; const MASK_31 : u64 = (1 << 31) - 1 ; const MOD : u64 = (1 << 61) - 1 ; pub struct RollingHash { hash : Vec < u64 > , pow : Vec < u64 > , } impl RollingHash { pub fn new (s : & [u8] , base : u64) -> RollingHash { let n = s . len () ; let mut hash : Vec < u64 > = vec ! [0 ; n + 1] ; let mut pow : Vec < u64 > = vec ! [0 ; n + 1] ; pow [0] = 1 ; for i in 0 .. n { pow [i + 1] = modulo (mod_mul (pow [i] , base)) ; hash [i + 1] = modulo (mod_mul (hash [i] , base) + s [i] as u64) ; } RollingHash { hash , pow } } # [doc = " Get hash of [l, r)"] pub fn get_hash (& self , l : usize , r : usize) -> u64 { modulo (self . hash [r] + MOD - mod_mul (self . hash [l] , self . pow [r - l])) } } fn mod_mul (a : u64 , b : u64) -> u64 { let (a_prefix , a_suffix) = (a >> 31 , a & MASK_31) ; let (b_prefix , b_suffix) = (b >> 31 , b & MASK_31) ; let m = a_suffix * b_prefix + a_prefix * b_suffix ; modulo (a_prefix * b_prefix * 2 + (m >> 30) + ((m & MASK_30) << 31) + a_suffix * b_suffix) } fn modulo (v : u64) -> u64 { let v = (v & MOD) + (v >> 61) ; if v >= MOD { v - MOD } else { v } } } # [cfg (test)] mod tests { use super :: * ; use rand :: distributions :: Uniform ; use rand :: Rng ; const BASE : u64 = 1_000_000_007 ; # [test] fn test_rolling_hash () { let n = 30 ; let mut rng = rand :: thread_rng () ; for _ in 0 .. 100 { let mut s = String :: new () ; for _ in 0 .. n { let c = (rng . sample (Uniform :: from (0 .. 26)) as u8 + 'a' as u8) as char ; s . push (c) ; } let t = String :: new () + s . as_str () + s . as_str () ; let n = t . len () ; let rolling_hash = rolling_hash :: RollingHash :: new (& t . as_bytes () , BASE) ; for i in 0 .. n { for j in i .. n { for k in (j + 1) .. n { let same = t [i .. k] == t [j .. k] ; let same_hash = rolling_hash . get_hash (i , k) == rolling_hash . get_hash (j , k) ; assert_eq ! (same , same_hash , "{:?} {:?} {} {}" , & t [i .. k] , & t [j .. k] , rolling_hash . get_hash (i , k) , rolling_hash . get_hash (j , k)) ; } } } } } } } pub mod z_algorithm { pub mod z_algorithm { pub fn calc_z_array < T : PartialEq > (s : & [T]) -> Vec < usize > { let n = s . len () ; let mut z_array = vec ! [0 ; n] ; let mut l = 0 ; let mut r = 1 ; for i in 1 .. n { if i >= r { l = i ; r = i + 1 ; while r <= n && s [r - 1 - l] == s [r - 1] { r += 1 ; } z_array [i] = r - l - 1 ; r -= 1 ; } else if z_array [i - l] < r - i { z_array [i] = z_array [i - l] ; } else { l = i ; while r <= n && s [r - 1 - l] == s [r - 1] { r += 1 ; } z_array [i] = r - l - 1 ; r -= 1 ; } } z_array [0] = n ; z_array } } # [cfg (test)] mod tests { use super :: * ; use rand :: distributions :: Uniform ; use rand :: Rng ; # [test] fn test_z () { let n = 1000 ; let mut rng = rand :: thread_rng () ; for _ in 0 .. 100 { let mut s = String :: new () ; for _ in 0 .. n { let c = (rng . sample (Uniform :: from (0 .. 26)) as u8 + 'a' as u8) as char ; s . push (c) ; } let t = String :: new () + s . as_str () + s . as_str () ; let z_array = z_algorithm :: calc_z_array (& t . as_bytes ()) ; let n = t . len () ; for i in 0 .. n { let l = z_array [i] ; assert_eq ! (& t [0 .. l] , & t [i .. (i + l)]) ; assert ! (i + l >= t . len () || t [l .. (l + 1)] != t [(i + l) .. (i + l + 1)]) ; } } } } } } }