Submission #56875669
Source Code Expand
use std::iter::successors;
use nekolib::fmt::SpaceSep;
use proconio::{input, marker::Usize1};
fn main() {
input! {
n: usize,
k: u64,
x: [Usize1; n],
a: [u32; n],
}
let f = N1FnGraph::new(&x);
let xk: Vec<_> = (0..n).map(|i| f.step(i, k)).collect();
let res: Vec<_> = xk.iter().map(|&i| a[i]).collect();
println!("{}", SpaceSep(&res));
}
struct N1FnGraph {
la: N1La,
cycle: Vec<Vec<usize>>,
}
impl N1FnGraph {
pub fn new(f: &[usize]) -> Self {
let (par, cycle) = Self::par_cycle(f);
let la = N1La::new(par);
Self { la, cycle }
}
pub fn step(&self, v: usize, k: u64) -> usize {
let d = self.la.depth(v);
debug_assert!(d > 0); // for sentinel `n`
if ((d - 1) as u64) >= k {
self.la.ascend(v, k as _)
} else {
let r = self.la.ascend(v, d - 1);
let k = k - (d - 1) as u64;
let lambda = self.cycle[r].len();
let i = (k % lambda as u64) as usize;
self.cycle[r][i]
}
}
fn par_cycle(f: &[usize]) -> (Vec<usize>, Vec<Vec<usize>>) {
let n = f.len();
let mut par = f.to_owned();
par.push(n + 1);
let mut cycle = vec![vec![]; n];
let mut seen = vec![false; n];
let mut stack = vec![];
let mut index = vec![n; n];
for mut i in 0..n {
while !seen[i] {
if index[i] < n {
break;
}
index[i] = stack.len();
stack.push(i);
i = f[i];
}
if !seen[i] {
let s = i;
let mut c = vec![];
while let Some(j) = stack.pop() {
c.push(j);
seen[j] = true;
if j == s {
break;
}
}
let r = c[0];
c.reverse();
c.rotate_right(1);
cycle[r] = c;
par[r] = n;
}
while let Some(j) = stack.pop() {
seen[j] = true;
}
}
(par, cycle)
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum RefNode {
MicroRoot(usize, usize),
MacroLeaf(usize),
}
use RefNode::{MacroLeaf, MicroRoot};
pub struct N1La {
par: Vec<usize>,
depth: Vec<usize>,
ref_node: Vec<RefNode>,
micro_tree: Vec<Option<(usize, Vec<usize>)>>,
jump_pointer: Vec<Vec<usize>>,
ladder: Vec<Vec<usize>>,
which_ladder: Vec<(usize, usize)>,
table: Vec<Vec<Vec<usize>>>,
}
impl N1La {
pub fn new(par: Vec<usize>) -> Self {
let n = par.len();
let thold = Self::thold(n);
let (g, r) = Self::children(&par);
let (depth, size) = Self::depth_size(&g, r);
let ref_node = Self::ref_node(&g, r, &depth, &size, &par, thold);
let micro_tree = Self::micro_tree(&g, &ref_node);
let jump_pointer = Self::jump_pointer(&g, r, &ref_node);
let (ladder, which_ladder) = Self::ladder(&g, &ref_node, &par);
let table = Self::table(µ_tree, thold);
Self {
par,
depth,
ref_node,
micro_tree,
jump_pointer,
ladder,
which_ladder,
table,
}
}
pub fn la(&self, v: usize, l: usize) -> usize {
assert!(self.depth[v] >= l);
self.ascend(v, self.depth(v) - l)
}
pub fn ascend(&self, v: usize, a: usize) -> usize {
assert!(self.depth[v] >= a);
let (v, a) = match self.ref_node[v] {
MicroRoot(r, ord) => {
if self.depth[v] - self.depth[r] >= a {
let &(e, ref vs) = self.micro_tree[r].as_ref().unwrap();
return vs[self.lookup(e, ord, a)];
} else {
(self.par[r], a - (self.depth[v] - self.depth[r] + 1))
}
}
_ => (v, a),
};
let (v, a) = match self.ref_node[v] {
MacroLeaf(u) => (u, a + (self.depth[u] - self.depth[v])),
MicroRoot(..) => unreachable!(),
};
// now v is a macro leaf, so it has jump pointers.
if a == 0 {
return v;
}
// use the appropriate jump pointer
let (v, a) = {
let msb = (usize::BITS - 1 - a.leading_zeros()) as usize;
(self.jump_pointer[v][msb], a - (1 << msb))
};
// use the appropriate ladder
let (i, j) = self.which_ladder[v];
self.ladder[i][a + j]
}
pub fn depth(&self, v: usize) -> usize { self.depth[v] }
fn thold(n: usize) -> usize {
(1..).take_while(|&i| (1_usize << (4 * i)) <= n).last().unwrap_or(1)
}
fn children(par: &[usize]) -> (Vec<Vec<usize>>, usize) {
let n = par.len();
let r = (0..n).find(|&i| par[i] == n).unwrap();
let mut g = vec![vec![]; n];
for i in 0..n {
if par[i] < n {
g[par[i]].push(i);
}
}
(g, r)
}
fn depth_size(g: &[Vec<usize>], r: usize) -> (Vec<usize>, Vec<usize>) {
fn dfs(
g: &[Vec<usize>],
v: usize,
depth: &mut [usize],
size: &mut [usize],
) {
for &nv in &g[v] {
depth[nv] = depth[v] + 1;
dfs(g, nv, depth, size);
size[v] += size[nv];
}
}
let n = g.len();
let mut depth = vec![0; n];
let mut size = vec![1; n];
dfs(g, r, &mut depth, &mut size);
(depth, size)
}
fn ref_node(
g: &[Vec<usize>],
r: usize,
depth: &[usize],
size: &[usize],
par: &[usize],
thold: usize,
) -> Vec<RefNode> {
fn dfs(
g: &[Vec<usize>],
v: usize,
size: &[usize],
thold: usize,
res: &mut [RefNode],
micro: &mut Option<&mut Vec<usize>>,
) {
if let Some(micro) = micro.as_mut() {
micro.push(v);
}
for &nv in &g[v] {
if size[nv] <= thold && size[v] > thold {
debug_assert!(micro.is_none());
let mut micro = vec![];
dfs(g, nv, size, thold, res, &mut Some(&mut micro));
for (i, &u) in micro.iter().enumerate() {
res[u] = MicroRoot(nv, i);
}
} else {
dfs(g, nv, size, thold, res, micro);
}
}
}
let n = g.len();
let mut res = vec![MacroLeaf(n); n];
dfs(g, r, size, thold, &mut res, &mut None);
let mut by_d = vec![vec![]; n];
for v in 0..n {
by_d[depth[v]].push(v);
}
for d in (0..n).rev() {
for &v in &by_d[d] {
if matches!(res[v], MicroRoot(..)) {
continue;
}
for u in successors(Some(v), |&v| (v < n).then(|| par[v]))
.take_while(|&u| u < n)
{
if res[u] != MacroLeaf(n) {
break;
}
res[u] = MacroLeaf(v);
}
}
}
res
}
fn micro_tree(
g: &[Vec<usize>],
ref_node: &[RefNode],
) -> Vec<Option<(usize, Vec<usize>)>> {
fn dfs(
g: &[Vec<usize>],
v: usize,
enc: &mut usize,
vs: &mut Vec<usize>,
) {
*enc = *enc << 1 | 1;
vs.push(v);
for &nv in &g[v] {
dfs(g, nv, enc, vs);
}
*enc = *enc << 1 | 0;
}
let n = g.len();
let mut res = vec![None; n];
for v in 0..n {
if let MicroRoot(_, 0) = ref_node[v] {
let mut enc = 0;
let mut vs = vec![];
dfs(g, v, &mut enc, &mut vs);
res[v] = Some((enc, vs));
}
}
res
}
fn jump_pointer(
g: &[Vec<usize>],
r: usize,
ref_node: &[RefNode],
) -> Vec<Vec<usize>> {
fn dfs(
g: &[Vec<usize>],
v: usize,
ref_node: &[RefNode],
path: &mut Vec<usize>,
res: &mut [Vec<usize>],
) {
path.push(v);
if let MacroLeaf(l) = ref_node[v] {
if v == l {
let pl = path.len();
res[v] = (0..)
.map(|i| 1 << i)
.take_while(|&i| i < pl)
.map(|i| path[pl - (i + 1)])
.collect();
} else {
for &nv in &g[v] {
dfs(g, nv, ref_node, path, res);
}
}
}
path.pop();
}
let n = g.len();
let mut res = vec![vec![]; n];
dfs(g, r, ref_node, &mut vec![], &mut res);
res
}
fn ladder(
g: &[Vec<usize>],
ref_node: &[RefNode],
par: &[usize],
) -> (Vec<Vec<usize>>, Vec<(usize, usize)>) {
let n = g.len();
let mut ladder = vec![vec![]; n];
let mut which_ladder = vec![(n, n); n];
let next_par1 = |v: usize| {
(par[v] < n && ref_node[par[v]] == ref_node[v]).then(|| par[v])
};
let next_par2 = |v: usize| (par[v] < n).then(|| par[v]);
for v in 0..n {
match ref_node[v] {
MacroLeaf(r) if r == v => (),
_ => continue,
}
ladder[v] = successors(Some(v), |&v| next_par1(v)).collect();
for (i, &u) in ladder[v].iter().enumerate() {
which_ladder[u] = (v, i);
}
let u = par[*ladder[v].last().unwrap()];
let k = ladder[v].len();
ladder[v].extend(
successors((u < n).then(|| u), |&v| next_par2(v)).take(k),
);
}
(ladder, which_ladder)
}
fn table(
micro_tree: &[Option<(usize, Vec<usize>)>],
thold: usize,
) -> Vec<Vec<Vec<usize>>> {
let mut res = vec![vec![]; 1 << (2 * thold)];
for &(e, ref vs) in micro_tree.iter().filter_map(|o| o.as_ref()) {
let len = vs.len();
let mut v = 0;
let mut path = vec![];
let mut res_e = vec![vec![]; len];
for b in (0..2 * len).rev().map(|i| e >> i & 1 != 0) {
if b {
path.push(v);
for &u in path.iter().rev() {
res_e[v].push(u);
}
v += 1;
} else {
path.pop();
}
}
res[e] = res_e;
}
res
}
fn lookup(&self, e: usize, v: usize, a: usize) -> usize {
self.table[e][v][a]
}
}
/// This module is bundled automatically.
/// See <https://rsk0315.github.io/nekolib/nekolib_doc/index.html> for documentation.
/// Commit: d829603bb021542857778d68b3de948ff48aff91-dirty
#[allow(unused)]
pub mod nekolib {
pub mod fmt {
pub mod str_sep {
use std::fmt;
pub struct SpaceSep<I>(pub I);
pub struct PerLine<I>(pub I);
pub struct StrSep<'a, I>(pub I, pub &'a str);
pub struct SpaceSepUsize1<I>(pub I);
pub struct PerLineUsize1<I>(pub I);
pub struct StrSepUsize1<'a, I>(pub I, pub &'a str);
macro_rules! impl_fmt {
( $( $fmt:ident )* ) => { $(
#[allow(non_snake_case)]
fn $fmt<I, T: fmt::$fmt>(iter: I, sep: &str, f: &mut fmt::Formatter<'_>) -> fmt::Result
where
I: IntoIterator<Item = T>,
{
let mut iter = iter.into_iter();
if let Some(first) = iter.by_ref().next() {
first.fmt(f)?;
}
iter.map(|rest| { write!(f, "{}", sep)?; rest.fmt(f) }).collect()
}
impl<I, T: fmt::$fmt> fmt::$fmt for SpaceSep<I>
where
I: IntoIterator<Item = T> + Clone,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
$fmt(self.0.clone(), " ", f)
}
}
impl<I, T: fmt::$fmt> fmt::$fmt for PerLine<I>
where
I: IntoIterator<Item = T> + Clone,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
$fmt(self.0.clone(), "\n", f)
}
}
impl<I, T: fmt::$fmt> fmt::$fmt for StrSep<'_, I>
where
I: IntoIterator<Item = T> + Clone,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
$fmt(self.0.clone(), self.1, f)
}
}
)* }
}
macro_rules! impl_fmt_usize1 {
( $( $fmt:ident )* ) => { $(
impl<I, T> fmt::$fmt for SpaceSepUsize1<I>
where
I: IntoIterator<Item = T> + Clone,
T: std::ops::Add<usize, Output = usize>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
$fmt(self.0.clone().into_iter().map(|u| u + 1), " ", f)
}
}
impl<I, T> fmt::$fmt for PerLineUsize1<I>
where
I: IntoIterator<Item = T> + Clone,
T: std::ops::Add<usize, Output = usize>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
$fmt(self.0.clone().into_iter().map(|u| u + 1), "\n", f)
}
}
impl<I, T> fmt::$fmt for StrSepUsize1<'_, I>
where
I: IntoIterator<Item = T> + Clone,
T: std::ops::Add<usize, Output = usize>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
$fmt(self.0.clone().into_iter().map(|u| u + 1), self.1, f)
}
}
)* }
}
impl_fmt! { Binary Debug Display LowerExp LowerHex Octal Pointer UpperExp UpperHex }
impl_fmt_usize1! { Debug Display LowerHex Octal UpperHex }
}
#[allow(unused_imports)]
pub use str_sep::*;
}
}
Submission Info
Submission Time |
|
Task |
E - Permute K times |
User |
rsk0315 |
Language |
Rust (rustc 1.70.0) |
Score |
450 |
Code Size |
15776 Byte |
Status |
AC |
Exec Time |
207 ms |
Memory |
95284 KiB |
Judge Result
Set Name |
Sample |
All |
Score / Max Score |
0 / 0 |
450 / 450 |
Status |
|
|
Set Name |
Test Cases |
Sample |
sample_01.txt, sample_02.txt, sample_03.txt |
All |
sample_01.txt, sample_02.txt, sample_03.txt, test_01.txt, test_02.txt, test_03.txt, test_04.txt, test_05.txt, test_06.txt, test_07.txt, test_08.txt, test_09.txt, test_10.txt, test_11.txt, test_12.txt, test_13.txt, test_14.txt, test_15.txt, test_16.txt, test_17.txt, test_18.txt, test_19.txt, test_20.txt, test_21.txt, test_22.txt, test_23.txt, test_24.txt, test_25.txt, test_26.txt, test_27.txt, test_28.txt, test_29.txt, test_30.txt, test_31.txt, test_32.txt, test_33.txt, test_34.txt, test_35.txt, test_36.txt, test_37.txt, test_38.txt, test_39.txt, test_40.txt, test_41.txt, test_42.txt, test_43.txt, test_44.txt, test_45.txt, test_46.txt, test_47.txt, test_48.txt, test_49.txt, test_50.txt, test_51.txt, test_52.txt, test_53.txt, test_54.txt, test_55.txt, test_56.txt, test_57.txt, test_58.txt, test_59.txt, test_60.txt, test_61.txt, test_62.txt, test_63.txt, test_64.txt, test_65.txt, test_66.txt, test_67.txt, test_68.txt, test_69.txt, test_70.txt, test_71.txt, test_72.txt, test_73.txt, test_74.txt, test_75.txt, test_76.txt, test_77.txt, test_78.txt, test_79.txt, test_80.txt |
Case Name |
Status |
Exec Time |
Memory |
sample_01.txt |
AC |
0 ms |
1876 KiB |
sample_02.txt |
AC |
0 ms |
1888 KiB |
sample_03.txt |
AC |
0 ms |
2100 KiB |
test_01.txt |
AC |
0 ms |
1884 KiB |
test_02.txt |
AC |
0 ms |
1940 KiB |
test_03.txt |
AC |
35 ms |
22900 KiB |
test_04.txt |
AC |
190 ms |
72036 KiB |
test_05.txt |
AC |
196 ms |
88560 KiB |
test_06.txt |
AC |
114 ms |
57452 KiB |
test_07.txt |
AC |
5 ms |
5484 KiB |
test_08.txt |
AC |
36 ms |
24128 KiB |
test_09.txt |
AC |
119 ms |
58020 KiB |
test_10.txt |
AC |
199 ms |
84744 KiB |
test_11.txt |
AC |
203 ms |
90436 KiB |
test_12.txt |
AC |
17 ms |
13224 KiB |
test_13.txt |
AC |
87 ms |
46692 KiB |
test_14.txt |
AC |
207 ms |
86604 KiB |
test_15.txt |
AC |
13 ms |
11932 KiB |
test_16.txt |
AC |
48 ms |
30280 KiB |
test_17.txt |
AC |
27 ms |
18940 KiB |
test_18.txt |
AC |
28 ms |
19340 KiB |
test_19.txt |
AC |
83 ms |
51220 KiB |
test_20.txt |
AC |
188 ms |
95284 KiB |
test_21.txt |
AC |
175 ms |
87904 KiB |
test_22.txt |
AC |
2 ms |
3616 KiB |
test_23.txt |
AC |
71 ms |
64472 KiB |
test_24.txt |
AC |
85 ms |
92716 KiB |
test_25.txt |
AC |
84 ms |
92636 KiB |
test_26.txt |
AC |
72 ms |
64352 KiB |
test_27.txt |
AC |
85 ms |
92492 KiB |
test_28.txt |
AC |
84 ms |
92716 KiB |
test_29.txt |
AC |
9 ms |
7892 KiB |
test_30.txt |
AC |
127 ms |
58636 KiB |
test_31.txt |
AC |
131 ms |
59748 KiB |
test_32.txt |
AC |
5 ms |
5556 KiB |
test_33.txt |
AC |
121 ms |
55932 KiB |
test_34.txt |
AC |
136 ms |
61692 KiB |
test_35.txt |
AC |
54 ms |
29820 KiB |
test_36.txt |
AC |
2 ms |
2936 KiB |
test_37.txt |
AC |
56 ms |
30668 KiB |
test_38.txt |
AC |
20 ms |
15428 KiB |
test_39.txt |
AC |
146 ms |
69796 KiB |
test_40.txt |
AC |
155 ms |
79080 KiB |
test_41.txt |
AC |
118 ms |
56984 KiB |
test_42.txt |
AC |
16 ms |
10652 KiB |
test_43.txt |
AC |
15 ms |
10220 KiB |
test_44.txt |
AC |
114 ms |
56700 KiB |
test_45.txt |
AC |
26 ms |
16476 KiB |
test_46.txt |
AC |
17 ms |
11572 KiB |
test_47.txt |
AC |
102 ms |
51436 KiB |
test_48.txt |
AC |
29 ms |
17848 KiB |
test_49.txt |
AC |
73 ms |
38852 KiB |
test_50.txt |
AC |
115 ms |
56928 KiB |
test_51.txt |
AC |
130 ms |
56640 KiB |
test_52.txt |
AC |
42 ms |
23396 KiB |
test_53.txt |
AC |
24 ms |
14608 KiB |
test_54.txt |
AC |
133 ms |
56580 KiB |
test_55.txt |
AC |
30 ms |
17584 KiB |
test_56.txt |
AC |
58 ms |
31196 KiB |
test_57.txt |
AC |
49 ms |
27252 KiB |
test_58.txt |
AC |
17 ms |
11176 KiB |
test_59.txt |
AC |
118 ms |
55188 KiB |
test_60.txt |
AC |
128 ms |
56168 KiB |
test_61.txt |
AC |
81 ms |
91052 KiB |
test_62.txt |
AC |
83 ms |
91052 KiB |
test_63.txt |
AC |
81 ms |
91156 KiB |
test_64.txt |
AC |
84 ms |
91056 KiB |
test_65.txt |
AC |
60 ms |
35492 KiB |
test_66.txt |
AC |
76 ms |
39056 KiB |
test_67.txt |
AC |
42 ms |
23764 KiB |
test_68.txt |
AC |
18 ms |
12444 KiB |
test_69.txt |
AC |
89 ms |
51292 KiB |
test_70.txt |
AC |
126 ms |
57844 KiB |
test_71.txt |
AC |
159 ms |
82428 KiB |
test_72.txt |
AC |
136 ms |
55144 KiB |
test_73.txt |
AC |
31 ms |
23304 KiB |
test_74.txt |
AC |
172 ms |
59448 KiB |
test_75.txt |
AC |
126 ms |
56664 KiB |
test_76.txt |
AC |
129 ms |
56844 KiB |
test_77.txt |
AC |
64 ms |
55248 KiB |
test_78.txt |
AC |
64 ms |
55176 KiB |
test_79.txt |
AC |
65 ms |
55252 KiB |
test_80.txt |
AC |
63 ms |
55000 KiB |