Submission #74676741
Source Code Expand
// ===========================================================================
// MAIN CODE
// ===========================================================================
use proconio::input;
use proconio::marker::Bytes;
fn main() {
input!{
s: Bytes,
t: Bytes,
}
let mut next = vec![[s.len(); 26]; s.len() + 1];
for i in (0..s.len()).rev(){
next[i] = next[i + 1];
next[i][(s[i] - b'a') as usize] = i;
}
let mut count = 0i64;
for i in 0..s.len(){
let mut cnt_pos = i;
let mut ok = true;
for &ct in &t{
if cnt_pos >=s.len(){
ok = false;
break;
}
let tugi = next[cnt_pos][(ct - b'a') as usize];
if tugi == s.len(){
ok = false;
break;
}
cnt_pos = tugi + 1;
}
if ok{
let r_min = cnt_pos - 1;
count += (s.len() - r_min) as i64;
}
}
let ans = (s.len() as i64 * (s.len() as i64 + 1)) / 2;
println!("{}", ans - count);
}
// ===========================================================================
// BUNDLED LIBRARY (kousaba_lib)
// ===========================================================================
pub mod kousaba_lib {
pub mod ds {
pub mod pos {
use std::mem::swap;
use std::cmp::max;
#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)]
pub struct Pos{
pub x: isize,
pub y: isize,
}
impl Pos{
pub fn new(x: isize, y: isize) -> Self { Self { x, y } }
pub fn as_isize(&self) -> (isize, isize) { (self.x, self.y) }
pub fn reverse(&mut self) -> &mut Pos {
swap(&mut self.x, &mut self.y);
self
}
pub fn reset(&mut self) -> &mut Pos{
self.x = 0;
self.y = 0;
self
}
pub fn norm_sq(&self) -> isize{ self.x * self.x + self.y * self.y }
pub fn norm(&self) -> f64{ (self.norm_sq() as f64).sqrt() }
pub fn dot(&self, other: &Pos) -> isize { self.x * other.x + self.y * other.y }
pub fn cross(&self, other: &Pos) -> isize { self.x * other.x - self.y * other.y }
pub fn manhattan_dis(&self, other: &Pos) -> isize { (self.x - other.x).abs() + (self.y - other.y).abs() }
pub fn distance_sq(&self, other: &Pos) -> isize { (self.x - other.x) * (self.x - other.x) + (self.y - other.y) * (self.y - other.y) }
pub fn distance(&self, other: &Pos) -> f64 { (self.distance_sq(other) as f64).sqrt() }
pub fn distance_4(&self, other: &Pos) -> isize { self.manhattan_dis(other) }
pub fn distance_8(&self, other: &Pos) -> isize { max(self.x - other.x, self.y - other.y) }
}
impl std::ops::Add for Pos{
type Output = Self;
fn add(self, rhs: Self) -> Self{
Pos::new(self.x + rhs.x, self.y + rhs.y)
}
}
impl std::ops::Sub for Pos{
type Output = Self;
fn sub(self, rhs: Self) -> Self{
Pos::new(self.x - rhs.x, self.y - rhs.y)
}
}
impl std::ops::AddAssign for Pos{
fn add_assign(&mut self, rhs: Self){
self.x += rhs.x;
self.y += rhs.y;
}
}
impl std::ops::SubAssign for Pos{
fn sub_assign(&mut self, rhs: Self){
self.x -= rhs.x;
self.y -= rhs.y;
}
}
} // mod pos
pub mod modint {
use std::marker::PhantomData;
use std::ops::{Add, AddAssign, Sub, SubAssign, Mul, MulAssign, Div, DivAssign};
pub trait Modulo: Copy + Clone{
fn mod_value() -> i64;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Mod1000000007;
impl Modulo for Mod1000000007 {
fn mod_value() -> i64 { 1_000_000_007 }
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Mod998244353;
impl Modulo for Mod998244353{
fn mod_value() -> i64 { 988_244_353 }
}
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct ModInt<M: Modulo>{
pub val: i64,
_phantom: PhantomData<fn() -> M>,
}
impl<M: Modulo> ModInt<M>{
pub fn new(v: i64) -> Self{
let m = M::mod_value();
ModInt{
val: v.rem_euclid(m), // 負の数でも正の剰余を返す
_phantom: PhantomData,
}
}
pub fn pow(self, mut n: u64) -> Self {
let mut res = Self::new(1);
let mut a = self;
while n > 0 {
if n & 1 == 1 {
res *= a;
}
a *= a;
n >>= 1;
}
res
}
pub fn inv(self) -> Self{
self.pow(M::mod_value() as u64 - 2)
}
}
impl<M: Modulo> std::fmt::Debug for ModInt<M> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.val)
}
}
impl<M: Modulo> std::fmt::Display for ModInt<M> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.val)
}
}
impl<M: Modulo> AddAssign for ModInt<M> {
fn add_assign(&mut self, rhs: Self) {
self.val += rhs.val;
if self.val >= M::mod_value() {
self.val -= M::mod_value();
}
}
}
impl<M: Modulo> SubAssign for ModInt<M> {
fn sub_assign(&mut self, rhs: Self) {
self.val -= rhs.val;
if self.val < 0 {
self.val += M::mod_value();
}
}
}
impl<M: Modulo> MulAssign for ModInt<M> {
fn mul_assign(&mut self, rhs: Self) {
self.val = (self.val * rhs.val) % M::mod_value();
}
}
impl<M: Modulo> DivAssign for ModInt<M> {
fn div_assign(&mut self, rhs: Self) {
*self *= rhs.inv();
}
}
impl<M: Modulo> Add for ModInt<M> {
type Output = Self;
fn add(self, rhs: Self) -> Self { let mut res = self; res += rhs; res }
}
impl<M: Modulo> Sub for ModInt<M> {
type Output = Self;
fn sub(self, rhs: Self) -> Self { let mut res = self; res -= rhs; res }
}
impl<M: Modulo> Mul for ModInt<M> {
type Output = Self;
fn mul(self, rhs: Self) -> Self { let mut res = self; res *= rhs; res }
}
impl<M: Modulo> Div for ModInt<M> {
type Output = Self;
fn div(self, rhs: Self) -> Self { let mut res = self; res /= rhs; res }
}
} // mod modint
pub mod segtree {
/*
How to use:
struct RangeSum;
impl Monoid for RangeSum{
type S = isize;
fn op(a: &Self::S, b: &Self::S) -> Self::S { a + b }
fn e() -> Self::S { 0 }
}
fn main(){
let v = vec![1, 2, 3, 4, 5];
let mut seg = SegTree::<RangeSum>::from(v);
println!("{}", seg.prod(0, 3)); // 1 + 2 + 3 = 6
seg.set(1, 10); // 2番目を10に変更(1, 10, 3, 4, 5)
seg.println!("{}", seg.prod(0, 3)); // 1 + 10 + 3 = 14
}
*/
use super::monoid::Monoid;
pub struct SegTree<M: Monoid>{
n: usize,
size: usize,
log: u32,
d: Vec<M::S>, // 1-indexed
}
impl<M: Monoid> SegTree<M>{
pub fn new(n: usize) -> Self{
vec![M::e(); n].into()
}
pub fn from(v: Vec<M::S>) -> Self{
let n = v.len();
let mut log = 0;
while (1 << log) < n { log += 1; }
let size = 1 << log;
let mut d = vec![M::e(); 2 * size];
for i in 0..n{
d[size + i] = v[i].clone();
}
let mut res = SegTree {n , size, log, d};
for i in (1..size).rev(){
res.update(i);
}
res
}
pub fn set(&mut self, mut p: usize, x: M::S){
assert!(p < self.n);
p += self.size;
self.d[p] = x;
for i in 1..=self.log{
self.update(p >> i);
}
}
pub fn get(&self, p: usize) -> &M::S{
assert!(p < self.n);
&self.d[p + self.size]
}
pub fn prod(&self, mut l: usize, mut r: usize) -> M::S{
assert!(l <= r && r <= self.n);
let mut sml = M::e();
let mut smr = M::e();
l += self.size;
r += self.size;
while l < r{
if l & 1 == 1{
sml = M::op(&sml, &self.d[l]);
l += 1;
}
if r & 1 == 1{
r -= 1;
smr = M::op(&self.d[r], &smr);
}
l >>= 1;
r >>= 1;
}
M::op(&sml, &smr)
}
pub fn all_prod(&self) -> &M::S{
&self.d[1]
}
pub fn max_right<F>(&self, mut l: usize, f: F) -> usize
where F: Fn(&M::S) -> bool {
assert!(l <= self.n);
assert!(f(&M::e()));
if l == self.n { return self.n; }
l += self.size;
let mut sm = M::e();
loop{
while l % 2 == 0 { l >>= 1; }
if !f(&M::op(&sm, &self.d[l])) {
while l < self.size{
l *= 2;
if f(&M::op(&sm, &self.d[l])){
sm = M::op(&sm, &self.d[l]);
l += 1;
}
}
return l - self.size;
}
sm = M::op(&sm, &self.d[l]);
l += 1;
if (l as isize & -(l as isize)) == l as isize { break; }
}
self.n
}
pub fn min_left<F>(&self, mut r: usize, f: F) -> usize
where F: Fn(&M::S) -> bool {
assert!(r <= self.n);
assert!(f(&M::e()));
if r == 0 { return 0; }
r += self.size;
let mut sm = M::e();
loop {
r -= 1;
while r > 1 && (r % 2 == 1) { r >>= 1; }
if !f(&M::op(&self.d[r], &sm)) {
while r < self.size {
r = 2 * r + 1;
if f(&M::op(&self.d[r], &sm)) {
sm = M::op(&self.d[r], &sm);
r -= 1;
}
}
return r + 1 - self.size;
}
sm = M::op(&self.d[r], &sm);
if (r as isize & -(r as isize)) == r as isize { break; }
}
0
}
fn update(&mut self, k: usize){
self.d[k] = M::op(&self.d[2 * k], &self.d[2 * k + 1]);
}
}
impl<M: Monoid> From<Vec<M::S>> for SegTree<M> {
fn from(v: Vec<M::S>) -> Self {
SegTree::from(v)
}
}
} // mod segtree
pub mod dynsegtree {
use super::monoid::Monoid;
pub struct DynSegTree<M: Monoid> {
root: Option<usize>,
range_l: i64,
range_r: i64,
nodes: Vec<Node<M::S>>,
}
struct Node<S> {
val: S,
left: Option<usize>,
right: Option<usize>,
}
impl<M: Monoid> DynSegTree<M> {
// 扱う範囲 [l, r) を指定
pub fn new(l: i64, r: i64) -> Self {
Self {
root: None,
range_l: l,
range_r: r,
nodes: Vec::new(),
}
}
fn create_node(&mut self) -> usize {
let idx = self.nodes.len();
self.nodes.push(Node {
val: M::e(),
left: None,
right: None,
});
idx
}
pub fn set(&mut self, p: i64, x: M::S) {
if self.root.is_none(){
let new_node = self.create_node();
self.root = Some(new_node);
}
let root = self.root.unwrap();
self._set(root, self.range_l, self.range_r, p, x);
}
fn _set(&mut self, node_idx: usize, l: i64, r: i64, p: i64, x: M::S) {
if r - l == 1 {
self.nodes[node_idx].val = x;
return;
}
let mid = l + (r - l) / 2;
if p < mid {
// 左の子ノードの有無を確認し、なければ作成
if self.nodes[node_idx].left.is_none() {
let new_node = self.create_node();
self.nodes[node_idx].left = Some(new_node);
}
let left_child = self.nodes[node_idx].left.unwrap();
self._set(left_child, l, mid, p, x);
} else {
// 右の子ノードの有無を確認し、なければ作成
if self.nodes[node_idx].right.is_none() {
let new_node = self.create_node();
self.nodes[node_idx].right = Some(new_node);
}
let right_child = self.nodes[node_idx].right.unwrap();
self._set(right_child, mid, r, p, x);
}
self.update(node_idx);
}
pub fn prod(&self, l: i64, r: i64) -> M::S {
if let Some(root) = self.root {
self._prod(root, self.range_l, self.range_r, l, r)
} else {
M::e()
}
}
fn _prod(&self, node_idx: usize, nl: i64, nr: i64, l: i64, r: i64) -> M::S {
if r <= nl || nr <= l { return M::e(); }
if l <= nl && nr <= r { return self.nodes[node_idx].val.clone(); }
let mid = nl + (nr - nl) / 2;
let vl = if let Some(left) = self.nodes[node_idx].left {
self._prod(left, nl, mid, l, r)
} else {
M::e()
};
let vr = if let Some(right) = self.nodes[node_idx].right {
self._prod(right, mid, nr, l, r)
} else {
M::e()
};
M::op(&vl, &vr)
}
fn update(&mut self, node_idx: usize) {
let e = M::e();
let l_val = self.nodes[node_idx].left.map(|i| &self.nodes[i].val).unwrap_or(&e);
let r_val = self.nodes[node_idx].right.map(|i| &self.nodes[i].val).unwrap_or(&e);
self.nodes[node_idx].val = M::op(l_val, r_val);
}
// 動的セグ木での二分探索 (max_right)
pub fn max_right<F>(&self, l: i64, f: F) -> i64
where F: Fn(&M::S) -> bool {
assert!(f(&M::e()));
let mut sm = M::e();
self._max_right(self.root, self.range_l, self.range_r, l, &f, &mut sm)
}
fn _max_right<F>(&self, node_idx: Option<usize>, nl: i64, nr: i64, l: i64, f: &F, sm: &mut M::S) -> i64
where F: Fn(&M::S) -> bool {
let e = M::e();
if nr <= l { return nr; }
if l <= nl {
let val = node_idx.map(|i| &self.nodes[i].val).unwrap_or(&e);
if f(&M::op(sm, val)) {
*sm = M::op(sm, val);
return nr;
}
if nr - nl == 1 { return nl; }
}
let mid = nl + (nr - nl) / 2;
let res = self._max_right(node_idx.and_then(|i| self.nodes[i].left), nl, mid, l, f, sm);
if res < mid { return res; }
self._max_right(node_idx.and_then(|i| self.nodes[i].right), mid, nr, l, f, sm)
}
}
} // mod dynsegtree
pub mod combinatorics {
use super::modint::{ModInt, Modulo};
pub struct Combinatorics<M: Modulo>{
fact: Vec<ModInt<M>>,
inv_fact: Vec<ModInt<M>>,
}
impl<M: Modulo> Combinatorics<M>{
pub fn new(n: usize) -> Self{
let mut fact = vec![ModInt::new(1); n + 1];
let mut inv_fact = vec![ModInt::new(1); n + 1];
for i in 1..n{
fact[i] =fact[i - 1] * ModInt::new(i as i64);
}
inv_fact[n] = fact[n].inv();
for i in (1..n).rev(){
inv_fact[i] = inv_fact[i + 1] * ModInt::new((i + 1) as i64);
}
Self{ fact, inv_fact }
}
pub fn npr(&self, n: usize, r: usize) -> ModInt<M>{
if n < r { return ModInt::new(0); }
self.fact[n] * self.inv_fact[n - r]
}
pub fn ncr(&self, n: usize, r: usize) -> ModInt<M>{
if n < r { return ModInt::new(0); }
self.fact[n] * self.inv_fact[r] * self.inv_fact[n - r]
}
pub fn nhr(&self, n: usize, r: usize) -> ModInt<M>{
if n == 0 && r == 0 { return ModInt::new(1); }
if n == 0 { return ModInt::new(0); }
self.ncr(n + r - 1, r)
}
pub fn fact(&self, n: usize) -> ModInt<M>{
self.fact[n]
}
}
} // mod combinatorics
pub mod dsu {
pub struct DSU{
parent_or_size: Vec<i32>,
}
impl DSU{
pub fn new(n: usize) -> Self{
Self{
parent_or_size: vec![-1; n],
}
}
pub fn leader(&mut self, a: usize) -> usize{
if self.parent_or_size[a] < 0{
return a;
}
self.parent_or_size[a] = self.leader(self.parent_or_size[a] as usize) as i32;
self.parent_or_size[a] as usize
}
pub fn merge(&mut self, a: usize, b: usize) -> bool {
let mut x = self.leader(a);
let mut y = self.leader(b);
if x == y { return false; }
// Union by Size: 小さい方を大きい方に繋ぐ
if -self.parent_or_size[x] < -self.parent_or_size[y] {
std::mem::swap(&mut x, &mut y);
}
self.parent_or_size[x] += self.parent_or_size[y];
self.parent_or_size[y] = x as i32;
true
}
pub fn same(&mut self, a: usize, b: usize) -> bool {
self.leader(a) == self.leader(b)
}
pub fn size(&mut self, a: usize) -> usize {
let leader = self.leader(a);
-self.parent_or_size[leader] as usize
}
pub fn groups(&mut self) -> Vec<Vec<usize>> {
let n = self.parent_or_size.len();
let mut leader_list = Vec::new();
for i in 0..n {
let l = self.leader(i);
if i == l { leader_list.push(i); }
}
let mut res = vec![Vec::new(); leader_list.len()];
for i in 0..n {
let l = self.leader(i);
let idx = leader_list.iter().position(|&x| x == l).unwrap();
res[idx].push(i);
}
res
}
}
} // mod dsu
pub mod lazysegtree {
use super::monoid::MapMonoid;
pub struct LazySegTree<M: MapMonoid> {
n: usize,
size: usize,
log: u32,
d: Vec<M::S>,
lz: Vec<M::F>,
}
impl<M: MapMonoid> LazySegTree<M> {
pub fn new(n: usize) -> Self {
let mut log = 0;
while (1 << log) < n { log += 1; }
let size = 1 << log;
Self {
n, size, log,
d: vec![M::e(); 2 * size],
lz: vec![M::id(); size],
}
}
fn update(&mut self, k: usize) {
self.d[k] = M::op(&self.d[2 * k], &self.d[2 * k + 1]);
}
fn all_apply(&mut self, k: usize, f: M::F) {
self.d[k] = M::mapping(&f, &self.d[k]);
if k < self.size {
self.lz[k] = M::composition(&f, &self.lz[k]);
}
}
fn push(&mut self, k: usize) {
let f = self.lz[k].clone();
if f != M::id() {
self.all_apply(2 * k, f.clone());
self.all_apply(2 * k + 1, f);
self.lz[k] = M::id();
}
}
pub fn apply(&mut self, mut l: usize, mut r: usize, f: M::F) {
if l == r { return; }
l += self.size;
r += self.size;
for i in (1..=self.log).rev() {
if ((l >> i) << i) != l { self.push(l >> i); }
if ((r >> i) << i) != r { self.push((r - 1) >> i); }
}
{
let (l2, r2) = (l, r);
while l < r {
if l & 1 == 1 { self.all_apply(l, f.clone()); l += 1; }
if r & 1 == 1 { r -= 1; self.all_apply(r, f.clone()); }
l >>= 1; r >>= 1;
}
l = l2; r = r2;
}
for i in 1..=self.log {
if ((l >> i) << i) != l { self.update(l >> i); }
if ((r >> i) << i) != r { self.update((r - 1) >> i); }
}
}
pub fn all_prod(&self) -> M::S {
self.d[1].clone()
}
}
} // mod lazysegtree
pub mod monoid {
use std::marker::PhantomData;
use std::ops::Add;
pub trait Monoid{
type S: Clone;
fn op(a: &Self::S, b: &Self::S) -> Self::S;
fn e() -> Self::S;
}
/// 区間和 (Sum)
pub struct Sum<T>(PhantomData<T>);
impl<T> Monoid for Sum<T>
where T: Clone + Copy + Add<Output = T> + Default {
type S = T;
fn op(a: &Self::S, b: &Self::S) -> Self::S { *a + *b }
fn e() -> Self::S { T::default() } // 数値型なら 0
}
/// 区間最小値 (Min)
pub struct Min<T>(PhantomData<T>);
impl<T> Monoid for Min<T>
where T: Clone + Copy + Ord + Bounded {
type S = T;
fn op(a: &Self::S, b: &Self::S) -> Self::S { *a.min(b) }
fn e() -> Self::S { T::max_value() }
}
/// 区間最大値 (Max)
pub struct Max<T>(PhantomData<T>);
impl<T> Monoid for Max<T>
where T: Clone + Copy + Ord + Bounded {
type S = T;
fn op(a: &Self::S, b: &Self::S) -> Self::S { *a.max(b) }
fn e() -> Self::S { T::min_value() }
}
pub trait Bounded {
fn min_value() -> Self;
fn max_value() -> Self;
}
impl Bounded for i64 { fn min_value() -> i64 { std::i64::MIN } fn max_value() -> i64 { std::i64::MAX } }
impl Bounded for i32 { fn min_value() -> i32 { std::i32::MIN } fn max_value() -> i32 { std::i32::MAX } }
pub trait MapMonoid {
type S: Clone; // データの型 (例: 区間最大値)
type F: Clone + PartialEq; // 作用素の型 (例: 加算値)
fn op(a: &Self::S, b: &Self::S) -> Self::S;
fn e() -> Self::S;
fn mapping(f: &Self::F, x: &Self::S) -> Self::S;
fn composition(f: &Self::F, g: &Self::F) -> Self::F;
fn id() -> Self::F;
}
/// パターンA: 区間加算・区間和 (Range Add, Range Sum)
pub struct RangeAddSum<T>(PhantomData<T>);
impl<T> MapMonoid for RangeAddSum<T>
where T: Clone + Copy + PartialEq + Add<Output = T> + std::ops::Mul<Output = T> + From<usize> + Default {
type S = ValSize<T>;
type F = T;
fn op(a: &Self::S, b: &Self::S) -> Self::S {
ValSize { val: a.val + b.val, size: a.size + b.size }
}
fn e() -> Self::S { ValSize { val: T::default(), size: 0 } }
fn mapping(f: &Self::F, x: &Self::S) -> Self::S {
// 新しい値 = 元の値 + (加算値 * 区間サイズ)
ValSize { val: x.val + *f * T::from(x.size), size: x.size }
}
fn composition(f: &Self::F, g: &Self::F) -> Self::F { *f + *g }
fn id() -> Self::F { T::default() }
}
/// パターンB: 区間加算・区間最小値 (Range Add, Range Min)
pub struct RangeAddMin<T>(PhantomData<T>);
impl<T> MapMonoid for RangeAddMin<T>
where T: Clone + Copy + Ord + Add<Output = T> + Bounded + Default + PartialEq {
type S = T;
type F = T;
fn op(a: &Self::S, b: &Self::S) -> Self::S { *a.min(b) }
fn e() -> Self::S { T::max_value() }
fn mapping(f: &Self::F, x: &Self::S) -> Self::S {
if *x == T::max_value() { *x } else { *x + *f }
}
fn composition(f: &Self::F, g: &Self::F) -> Self::F { *f + *g }
fn id() -> Self::F { T::default() }
}
/// パターンC: 区間更新・区間最小値 (Range Update, Range Min)
pub struct RangeUpdateMin<T>(PhantomData<T>);
impl<T> MapMonoid for RangeUpdateMin<T>
where T: Clone + Copy + Ord + Bounded + PartialEq {
type S = T;
type F = Option<T>; // None を「更新なし(単位元)」とする
fn op(a: &Self::S, b: &Self::S) -> Self::S { *a.min(b) }
fn e() -> Self::S { T::max_value() }
fn mapping(f: &Self::F, x: &Self::S) -> Self::S { f.unwrap_or(*x) }
fn composition(f: &Self::F, g: &Self::F) -> Self::F { f.or(*g) }
fn id() -> Self::F { None }
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct ValSize<T> {
pub val: T,
pub size: usize,
}
} // mod monoid
pub mod mergesorttree {
pub struct MergeSortTree<T>{
n: usize,
tree: Vec<Vec<T>>,
}
impl<T: Ord + Clone + Copy> MergeSortTree<T>{
pub fn new(v: &[T]) -> Self{
let n = v.len();
let mut size = 1;
while size < n { size *= 2; }
let mut tree = vec![vec![]; 2 * size];
for i in 0..n{
tree[size + i] = vec![v[i]];
}
for i in (1..size).rev(){
let left = &tree[2 * i];
let right = &tree[2 * i + 1];
tree[i] = Self::merge(left, right);
}
Self { n, tree }
}
fn merge(a: &[T], b: &[T]) -> Vec<T>{
let mut res = Vec::with_capacity(a.len() + b.len());
let (mut i, mut j) = (0, 0);
while i < a.len() && j < b.len(){
if a[i] <= b[j]{
res.push(a[i]);
i += 1;
}else{
res.push(b[j]);
j += 1;
}
}
res.extend_from_slice(&a[i..]);
res.extend_from_slice(&b[j..]);
res
}
pub fn count_less_than(&self, mut l: usize, mut r: usize, x: T) -> usize{
let size = self.tree.len() / 2;
l += size;
r += size;
let mut count = 0;
while l < r{
if l & r == 1{
count += self.tree[l].partition_point(|&val| val < x);
l += 1;
}
if r & 1 == 1{
r -= 1;
count += self.tree[r].partition_point(|&val| val < x);
}
l >>= 1;
r >>= 1;
}
count
}
}
} // mod mergesorttree
pub mod graph {
use std::collections::{BinaryHeap, VecDeque};
use std::marker::PhantomData;
use std::cmp::Reverse;
// --- 1. 状態マーカーとトレイト ---
pub trait StorageStrategy: 'static { const IS_DYNAMIC: bool; }
pub struct Static;
pub struct Dynamic;
impl StorageStrategy for Static { const IS_DYNAMIC: bool = false; }
impl StorageStrategy for Dynamic { const IS_DYNAMIC: bool = true; }
pub trait DirectionStrategy: 'static { const IS_DIRECTED: bool; }
pub struct Directed;
pub struct Undirected;
impl DirectionStrategy for Directed { const IS_DIRECTED: bool = true; }
impl DirectionStrategy for Undirected { const IS_DIRECTED: bool = false; }
#[derive(Clone, Copy, Debug)]
pub struct Edge {
pub to: usize,
pub weight: i64,
}
// --- 2. グラフの解析情報 ---
#[derive(Debug, Clone, Default)]
pub struct GraphMetadata {
pub is_dag: bool,
pub is_tree: bool,
pub is_01: bool,
pub is_unweighted: bool,
pub component_count: usize,
pub topological_order: Vec<usize>,
}
// --- 3. グラフ本体 ---
pub struct Graph<S: StorageStrategy, D: DirectionStrategy> {
pub n: usize,
raw_edges: Vec<(usize, usize, i64)>,
pub adj: Vec<Vec<Edge>>,
pub meta: Option<GraphMetadata>,
_s: PhantomData<S>,
_d: PhantomData<D>,
}
// --- 4. ビルダーの実装 (new メソッドの場所を修正) ---
pub struct GraphConfig { n: usize }
pub struct GraphConfigWithS<S: StorageStrategy> { n: usize, _s: PhantomData<S> }
impl GraphConfig {
pub fn static_(self) -> GraphConfigWithS<Static> {
GraphConfigWithS { n: self.n, _s: PhantomData }
}
pub fn dynamic(self) -> GraphConfigWithS<Dynamic> {
GraphConfigWithS { n: self.n, _s: PhantomData }
}
}
impl<S: StorageStrategy> GraphConfigWithS<S> {
pub fn directed(self) -> Graph<S, Directed> {
Graph::init(self.n)
}
pub fn undirected(self) -> Graph<S, Undirected> {
Graph::init(self.n)
}
}
// Graph 構造体に対する実装
impl<S: StorageStrategy, D: DirectionStrategy> Graph<S, D> {
// 内部的な初期化用
fn init(n: usize) -> Self {
Self {
n,
raw_edges: Vec::new(),
adj: vec![Vec::new(); n],
meta: None,
_s: PhantomData,
_d: PhantomData,
}
}
// 外部から呼ぶ唯一の入り口
pub fn new(n: usize) -> GraphConfig {
GraphConfig { n }
}
pub fn add_edge(&mut self, u: usize, v: usize, w: i64) {
self.raw_edges.push((u, v, w));
if S::IS_DYNAMIC {
self.adj[u].push(Edge { to: v, weight: w });
if !D::IS_DIRECTED {
self.adj[v].push(Edge { to: u, weight: w });
}
}
}
}
// --- 5. Static 専用の build メソッド ---
impl<D: DirectionStrategy> Graph<Static, D> {
pub fn build(&mut self) {
let mut meta = GraphMetadata::default();
let mut in_degree = vec![0; self.n];
let mut is_01 = true;
let mut is_unweighted = true;
// 隣接リスト構築
for a in &mut self.adj { a.clear(); }
for &(u, v, w) in &self.raw_edges {
self.adj[u].push(Edge { to: v, weight: w });
if D::IS_DIRECTED {
in_degree[v] += 1;
} else {
self.adj[v].push(Edge { to: u, weight: w });
}
if w != 0 && w != 1 { is_01 = false; }
if w != 1 { is_unweighted = false; }
}
meta.is_01 = is_01;
meta.is_unweighted = is_unweighted;
// DAG判定 (有向のみ)
if D::IS_DIRECTED {
let mut queue = VecDeque::new();
let mut temp_in_degree = in_degree.clone();
for i in 0..self.n {
if temp_in_degree[i] == 0 { queue.push_back(i); }
}
while let Some(u) = queue.pop_front() {
meta.topological_order.push(u);
for e in &self.adj[u] {
temp_in_degree[e.to] -= 1;
if temp_in_degree[e.to] == 0 { queue.push_back(e.to); }
}
}
meta.is_dag = meta.topological_order.len() == self.n;
} else {
meta.is_dag = false; // 無向グラフは通常DAGとは呼ばない
}
// 連結成分数カウント
let mut visited = vec![false; self.n];
let mut component_count = 0;
for i in 0..self.n {
if !visited[i] {
component_count += 1;
let mut q = VecDeque::new();
q.push_back(i);
visited[i] = true;
while let Some(u) = q.pop_front() {
for e in &self.adj[u] {
if !visited[e.to] {
visited[e.to] = true;
q.push_back(e.to);
}
}
}
}
}
meta.component_count = component_count;
// 木判定
// 無向: 連結かつ辺が N-1 / 有向: 弱連結かつ辺が N-1 かつ DAG
let edge_count = self.raw_edges.len();
if !D::IS_DIRECTED {
meta.is_tree = component_count == 1 && edge_count == self.n - 1;
} else {
meta.is_tree = meta.is_dag && component_count == 1 && edge_count == self.n - 1;
}
self.meta = Some(meta);
}
}
impl<S: StorageStrategy, D: DirectionStrategy> Graph<S, D> {
/// 隣接頂点の一覧を返す
pub fn neighbors(&self, u: usize) -> &[Edge] {
&self.adj[u]
}
/// 重みをすべて1とみなした時の最短距離 (通常のBFS)
pub fn bfs(&self, start: usize) -> Vec<Option<i64>> {
let mut dist = vec![None; self.n];
let mut que = VecDeque::new();
dist[start] = Some(0);
que.push_back(start);
while let Some(u) = que.pop_front() {
let d = dist[u].unwrap();
for e in &self.adj[u] {
if dist[e.to].is_none() {
dist[e.to] = Some(d + 1);
que.push_back(e.to);
}
}
}
dist
}
/// 最短経路 (SSSP): meta情報を元に最適化
pub fn dist_from(&self, start: usize) -> Vec<Option<i64>> {
if let Some(ref m) = self.meta {
if m.is_dag {
return self.dist_dag(start);
}
if m.is_unweighted {
return self.bfs(start);
}
if m.is_01 {
return self.bfs_01(start);
}
}
self.dijkstra(start)
}
/// 01-BFS: 重みが 0 または 1 の場合のみ使用可能
fn bfs_01(&self, start: usize) -> Vec<Option<i64>> {
let mut dist = vec![None; self.n];
let mut que = VecDeque::new();
dist[start] = Some(0);
que.push_back(start);
while let Some(u) = que.pop_front() {
let d = dist[u].unwrap();
for e in &self.adj[u] {
let next_d = d + e.weight;
if dist[e.to].is_none() || next_d < dist[e.to].unwrap() {
dist[e.to] = Some(next_d);
if e.weight == 0 {
que.push_front(e.to);
} else {
que.push_back(e.to);
}
}
}
}
dist
}
/// DAG上の最短経路 (トポロジカルソート順DP)
fn dist_dag(&self, start: usize) -> Vec<Option<i64>> {
let mut dist = vec![None; self.n];
dist[start] = Some(0);
let order = &self.meta.as_ref().unwrap().topological_order;
// トポロジカル順に更新
for &u in order {
if let Some(d) = dist[u] {
for e in &self.adj[u] {
if dist[e.to].is_none() || d + e.weight < dist[e.to].unwrap() {
dist[e.to] = Some(d + e.weight);
}
}
}
}
dist
}
/// ダイクストラ法: 一般的な非負重みグラフ用
pub fn dijkstra(&self, start: usize) -> Vec<Option<i64>> {
let mut dist = vec![None; self.n];
let mut pq = BinaryHeap::new();
dist[start] = Some(0);
pq.push(Reverse((0, start)));
while let Some(Reverse((d, u))) = pq.pop() {
if Some(d) > dist[u] { continue; }
for e in &self.adj[u] {
let next_d = d + e.weight;
if dist[e.to].is_none() || next_d < dist[e.to].unwrap() {
dist[e.to] = Some(next_d);
pq.push(Reverse((next_d, e.to)));
}
}
}
dist
}
/// 全点対間最短距離 (APSP)
pub fn dist_all(&self) -> Vec<Vec<Option<i64>>> {
// 頂点数が少なければ ワーシャルフロイド
if self.n <= 400 {
self.warshall_floyd()
} else {
// 頂点数が多ければ 各点からダイクストラ
(0..self.n).map(|i| self.dist_from(i)).collect()
}
}
fn warshall_floyd(&self) -> Vec<Vec<Option<i64>>> {
let mut dist = vec![vec![None; self.n]; self.n];
for i in 0..self.n { dist[i][i] = Some(0); }
for u in 0..self.n {
for e in &self.adj[u] {
let d = Some(e.weight);
if dist[u][e.to].is_none() || d < dist[u][e.to] {
dist[u][e.to] = d;
}
}
}
for k in 0..self.n {
for i in 0..self.n {
for j in 0..self.n {
if let (Some(ik), Some(kj)) = (dist[i][k], dist[k][j]) {
if dist[i][j].is_none() || ik + kj < dist[i][j].unwrap() {
dist[i][j] = Some(ik + kj);
}
}
}
}
}
dist
}
}
} // mod graph
pub mod rangeset {
use std::collections::BTreeSet;
use std::cmp::{max, min};
use std::ops::RangeFrom;
#[derive(Debug, Clone, Default)]
pub struct RangeSet {
// [l, r] の閉区間を保持。l を基準にソートされる
set: BTreeSet<(i64, i64)>,
total_len: i64,
}
impl RangeSet {
pub fn new() -> Self {
Self {
set: BTreeSet::new(),
total_len: 0,
}
}
/// [l, r] を追加する O(log N)
pub fn insert(&mut self, mut l: i64, mut r: i64) {
if l > r { return; }
let overlaps = self.drain_overlaps(l - 1, r + 1);
for (sl, sr) in overlaps {
l = min(l, sl);
r = max(r, sr);
}
self.set.insert((l, r));
self.total_len += r - l + 1;
}
/// [l, r] を削除する O(log N)
pub fn erase(&mut self, l: i64, r: i64) {
if l > r { return; }
let overlaps = self.drain_overlaps(l, r);
for (sl, sr) in overlaps {
if sl < l {
self.set.insert((sl, l - 1));
self.total_len += (l - 1) - sl + 1;
}
if r < sr {
self.set.insert((r + 1, sr));
self.total_len += sr - (r + 1) + 1;
}
}
}
/// x 以上で含まれていない最小の整数 O(log N)
pub fn mex(&self, x: i64) -> i64 {
if let Some((_, sr)) = self.span(x) {
sr + 1
} else {
x
}
}
pub fn min(&self) -> Option<i64> {
self.set.first().map(|&(l, _)| l)
}
pub fn max(&self) -> Option<i64> {
self.set.last().map(|&(_, r)| r)
}
/// 小さい方から k 番目(0-indexed)の値を返す O(区間数)
pub fn kth(&self, mut k: i64) -> Option<i64> {
if k < 0 || k >= self.total_len { return None; }
for &(l, r) in &self.set {
let len = r - l + 1;
if k < len { return Some(l + k); }
k -= len;
}
None
}
/// 区間 [l, r] のうち、集合に含まれている整数の個数 O(log N)
pub fn count_in(&self, l: i64, r: i64) -> i64 {
if l > r { return 0; }
let mut count = 0;
for &(sl, sr) in self.set.range(self.range_from(l)) {
if r < sl { break; }
let il = max(l, sl);
let ir = min(r, sr);
if il <= ir { count += ir - il + 1; }
}
count
}
/// [l, r] 内の「隙間」を返す O(log N)
pub fn find_gap(&self, l: i64, r: i64) -> Vec<(i64, i64)> {
let mut gaps = Vec::new();
let mut curr = l;
for &(sl, sr) in self.set.range(self.range_from(l)) {
if r < curr { break; }
if curr < sl {
gaps.push((curr, min(r, sl - 1)));
}
curr = max(curr, sr + 1);
}
if curr <= r { gaps.push((curr, r)); }
gaps
}
pub fn span(&self, x: i64) -> Option<(i64, i64)> {
if let Some(&(sl, sr)) = self.set.range(self.range_from(x)).next() {
if sl <= x && x <= sr { return Some((sl, sr)); }
}
None
}
pub fn contains(&self, x: i64) -> bool { self.span(x).is_some() }
pub fn len(&self) -> i64 { self.total_len }
// --- 内部ヘルパー ---
/// 指定範囲 [l, r] と重なる区間を削除して返す
fn drain_overlaps(&mut self, l: i64, r: i64) -> Vec<(i64, i64)> {
let mut removed = Vec::new();
// ここが修正ポイント:range_fromの結果をそのまま使う
let it = self.set.range(self.range_from(l)).cloned().collect::<Vec<_>>();
for (sl, sr) in it {
if r < sl { break; }
if max(l, sl) <= min(r, sr) {
self.total_len -= sr - sl + 1;
self.set.remove(&(sl, sr));
removed.push((sl, sr));
}
}
removed
}
/// x を含む可能性がある「最も左の区間」を起点とする範囲オブジェクトを返す
fn range_from(&self, x: i64) -> RangeFrom<(i64, i64)> {
// x 以下の start を持つ最大の区間を探す
if let Some(&prev) = self.set.range(..(x, std::i64::MAX)).next_back() {
prev..
} else {
(std::i64::MIN, std::i64::MIN)..
}
}
}
} // mod rangeset
pub mod potentialdsu {
/*
fn main() {
let mut dsu = PotentialDSU::new(5);
// V[1] = V[0] + 5 (1は0より5大きい)
dsu.merge(0, 1, 5);
// V[2] = V[1] + 3 (2は1より3大きい)
dsu.merge(1, 2, 3);
// 0 から見た 2 の差は?
if let Some(d) = dsu.diff(0, 2) {
println!("V[2] - V[0] = {}", d); // 8
}
// 矛盾する情報を入れようとすると false が返る
let success = dsu.merge(0, 2, 10); // 実際は 8 なので矛盾
println!("Merge success: {}", success); // false
}
*/
pub struct PotentialDSU{
parent_or_size: Vec<i32>,
diff_weight: Vec<i64>,
}
impl PotentialDSU{
pub fn new(n: usize) -> Self{
Self{
parent_or_size: vec![-1; n],
diff_weight: vec![0; n],
}
}
/// 根を探す。同時に経路圧縮を行い、ポテンシャルを「根からの差」に更新する
pub fn leader(&mut self, a: usize) -> usize {
if self.parent_or_size[a] < 0 {
return a;
}
let root = self.leader(self.parent_or_size[a] as usize);
// 親がさらに上の親(最終的に根)に繋ぎ変わるので、重みも累積させる
self.diff_weight[a] += self.diff_weight[self.parent_or_size[a] as usize];
self.parent_or_size[a] = root as i32;
root
}
/// a から見た b のポテンシャル(V[b] - V[a])を返す
/// 同じグループにいない場合は None
pub fn diff(&mut self, a: usize, b: usize) -> Option<i64> {
if self.leader(a) != self.leader(b) {
return None;
}
// V[b] - V[root] - (V[a] - V[root]) = V[b] - V[a]
Some(self.diff_weight[b] - self.diff_weight[a])
}
/// V[b] = V[a] + w となるように関係性を登録する
/// すでに同じグループにいて、矛盾が発生する場合は false を返す
pub fn merge(&mut self, a: usize, b: usize, mut w: i64) -> bool {
let mut root_a = self.leader(a);
let mut root_b = self.leader(b);
if root_a == root_b {
// すでに同じグループなら、既存の差と矛盾しないかチェック
return self.diff(a, b) == Some(w);
}
// V[b] = V[a] + w
// V[b] = V[root_b] + dw[b]
// V[a] = V[root_a] + dw[a]
// => V[root_b] + dw[b] = V[root_a] + dw[a] + w
// => V[root_b] = V[root_a] + (w + dw[a] - dw[b])
w += self.diff_weight[a];
w -= self.diff_weight[b];
// Union by size
if -self.parent_or_size[root_a] < -self.parent_or_size[root_b] {
std::mem::swap(&mut root_a, &mut root_b);
w = -w;
}
self.parent_or_size[root_a] += self.parent_or_size[root_b];
self.parent_or_size[root_b] = root_a as i32;
self.diff_weight[root_b] = w;
true
}
pub fn same(&mut self, a: usize, b: usize) -> bool {
self.leader(a) == self.leader(b)
}
pub fn size(&mut self, a: usize) -> usize {
let leader = self.leader(a);
-self.parent_or_size[leader] as usize
}
}
} // mod potentialdsu
pub mod treap {
/*
fn main() {
let mut tr = Treap::new();
tr.insert(0, 10);
tr.insert(1, 20);
tr.insert(2, 30); // [10, 20, 30]
tr.reverse(0, 2); // [20, 10, 30]
println!("sum(0..2): {}", tr.range_sum(0, 2)); // 20 + 10 = 30
println!("val at 0: {}", tr.range_sum(0, 1)); // 20
}
*/
use std::time::{SystemTime, UNIX_EPOCH};
// シンプルな乱数生成器
#[derive(Debug)]
struct Random(u64);
impl Random {
fn new() -> Self {
let s = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_nanos() as u64;
Self(s)
}
fn next(&mut self) -> u64 {
self.0 ^= self.0 << 13;
self.0 ^= self.0 >> 7;
self.0 ^= self.0 << 17;
self.0
}
}
#[derive(Clone, Debug)]
struct Node {
val: i64,
sum: i64, // 区間和(セグ木機能)
priority: u64,
size: usize,
left: Option<usize>,
right: Option<usize>,
rev: bool, // 反転フラグ
}
#[derive(Debug)]
pub struct Treap {
nodes: Vec<Node>,
root: Option<usize>,
rng: Random,
}
impl Treap {
pub fn new() -> Self {
Self {
nodes: Vec::new(),
root: None,
rng: Random::new(),
}
}
fn create_node(&mut self, val: i64) -> usize {
let idx = self.nodes.len();
self.nodes.push(Node {
val,
sum: val,
priority: self.rng.next(),
size: 1,
left: None,
right: None,
rev: false,
});
idx
}
fn get_size(&self, idx: Option<usize>) -> usize {
idx.map_or(0, |i| self.nodes[i].size)
}
fn get_sum(&self, idx: Option<usize>) -> i64 {
idx.map_or(0, |i| self.nodes[i].sum)
}
// 子の情報から自分の size と sum を更新
fn update(&mut self, idx: usize) {
// 1. まず、子のインデックスをコピーして取得する
// これにより self.nodes[idx] への借用をすぐに終わらせる
let left_idx = self.nodes[idx].left;
let right_idx = self.nodes[idx].right;
// 2. 子の情報を計算する (self.get_size や self.get_sum を安全に呼べる)
let left_size = self.get_size(left_idx);
let right_size = self.get_size(right_idx);
let left_sum = self.get_sum(left_idx);
let right_sum = self.get_sum(right_idx);
// 3. 最後に自分自身のノードを取得して値を書き換える
let node = &mut self.nodes[idx];
node.size = 1 + left_size + right_size;
node.sum = node.val + left_sum + right_sum;
}
// 遅延フラグを下ろす(反転処理)
fn push(&mut self, idx: Option<usize>) {
if let Some(i) = idx {
// 1. まず反転フラグが立っているかチェック
if self.nodes[i].rev {
// フラグを倒す
self.nodes[i].rev = false;
// 2. 子のインデックスを「値」としてコピーして取り出す
// これで self.nodes[i] への参照は不要になる
let l_idx = self.nodes[i].left;
let r_idx = self.nodes[i].right;
// 3. 左右を入れ替える
self.nodes[i].left = r_idx;
self.nodes[i].right = l_idx;
// 4. 子にフラグを伝搬させる
// 参照ではなくインデックス(usize)を使っているので、
// 別々にアクセスしても借用エラーにならない
if let Some(li) = self.nodes[i].left {
self.nodes[li].rev ^= true;
}
if let Some(ri) = self.nodes[i].right {
self.nodes[ri].rev ^= true;
}
}
}
}
// 分割: [0, k) と [k, n) に分ける
fn split(&mut self, node: Option<usize>, k: usize) -> (Option<usize>, Option<usize>) {
if node.is_none() { return (None, None); }
let idx = node.unwrap();
self.push(Some(idx));
let left_size = self.get_size(self.nodes[idx].left);
if k <= left_size {
// 左側をさらに分割
let left_child = self.nodes[idx].left;
let (l, r) = self.split(left_child, k);
self.nodes[idx].left = r;
self.update(idx);
(l, Some(idx))
} else {
// 右側をさらに分割
let right_child = self.nodes[idx].right;
let (l, r) = self.split(right_child, k - left_size - 1);
self.nodes[idx].right = l;
self.update(idx);
(Some(idx), r)
}
}
// マージ: 2つの木を合体させる
fn merge(&mut self, l: Option<usize>, r: Option<usize>) -> Option<usize> {
self.push(l);
self.push(r);
match (l, r) {
(None, r) => r,
(l, None) => l,
(Some(li), Some(ri)) => {
if self.nodes[li].priority > self.nodes[ri].priority {
let right_child = self.nodes[li].right;
self.nodes[li].right = self.merge(right_child, Some(ri));
self.update(li);
Some(li)
} else {
let left_child = self.nodes[ri].left;
self.nodes[ri].left = self.merge(Some(li), left_child);
self.update(ri);
Some(ri)
}
}
}
}
// --- 公開メソッド(ボロチェッカー対策済み) ---
pub fn insert(&mut self, i: usize, val: i64) {
let (l, r) = self.split(self.root, i);
let mid = Some(self.create_node(val));
let tmp = self.merge(l, mid); // ネストせず一旦変数に置く
self.root = self.merge(tmp, r);
}
pub fn erase(&mut self, i: usize) {
let (l, mid_r) = self.split(self.root, i);
let (_mid, r) = self.split(mid_r, 1);
self.root = self.merge(l, r);
}
pub fn reverse(&mut self, l: usize, r: usize) {
let (left, mid_right) = self.split(self.root, l);
let (mid, right) = self.split(mid_right, r - l);
if let Some(m) = mid {
self.nodes[m].rev ^= true;
}
let tmp = self.merge(left, mid);
self.root = self.merge(tmp, right);
}
pub fn range_sum(&mut self, l: usize, r: usize) -> i64 {
let (left, mid_right) = self.split(self.root, l);
let (mid, right) = self.split(mid_right, r - l);
let res = self.get_sum(mid);
let tmp = self.merge(left, mid);
self.root = self.merge(tmp, right);
res
}
pub fn len(&self) -> usize {
self.get_size(self.root)
}
}
} // mod treap
} // mod ds
pub mod prelude {
pub trait ChangeMinMax{
fn chmin(&mut self, val: Self) -> bool;
fn chmax(&mut self, val: Self) -> bool;
}
impl<T: PartialOrd> ChangeMinMax for T {
fn chmin(&mut self, val: Self) -> bool {
if *self > val { *self = val; true } else { false }
}
fn chmax(&mut self, val: Self) -> bool {
if *self < val { *self = val; true } else { false }
}
}
pub mod math {
/// 最大公約数
pub fn gcd(a: u64, b: u64) -> u64 {
if b == 0 { a } else { gcd(b, a % b) }
}
/// 最小公倍数
pub fn lcm(a: u64, b: u64) -> u64 {
if a == 0 || b == 0 { 0 } else { (a / gcd(a, b)) * b }
}
/// 繰り返し二乗法 (a^n % m)
pub fn pow_mod(mut a: u64, mut n: u64, m: u64) -> u64 {
let mut res = 1 % m;
a %= m;
while n > 0 {
if n % 2 == 1 { res = res * a % m; }
a = a * a % m;
n /= 2;
}
res
}
/// エラトステネスの篩 (n以下の素数判定テーブル)
pub fn sieve(n: usize) -> Vec<bool> {
let mut is_prime = vec![true; n + 1];
is_prime[0] = false; is_prime[1] = false;
for i in 2..=((n as f64).sqrt() as usize) {
if is_prime[i] {
for j in (i * i..=n).step_by(i) { is_prime[j] = false; }
}
}
is_prime
}
}
pub fn compress<T: Ord + Clone>(a: &[T]) -> Vec<usize> {
let mut vals = a.to_vec();
vals.sort_unstable();
vals.dedup();
a.iter().map(|x| vals.binary_search(x).unwrap()).collect()
}
} // mod prelude
pub mod math {
} // mod math
}
Submission Info
Submission Time
2026-04-04 21:56:14+0900
Task
D - No-Subsequence Substring
User
kousaba
Language
Rust (rustc 1.89.0)
Score
400
Code Size
50252 Byte
Status
AC
Exec Time
40 ms
Memory
42848 KiB
Compile Error
warning: field `n` is never read
--> src/main.rs:606:5
|
605 | pub struct LazySegTree<M: MapMonoid> {
| ----------- field in this struct
606 | n: usize,
| ^
|
= note: `#[warn(dead_code)]` on by default
warning: field `n` is never read
--> src/main.rs:786:5
|
785 | pub struct MergeSortTree<T>{
| ------------- field in this struct
786 | n: usize,
| ^
Judge Result
Set Name
Sample
All
Score / Max Score
0 / 0
400 / 400
Status
Set Name
Test Cases
Sample
00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt
All
00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt, 01_random_03.txt, 01_random_04.txt, 01_random_05.txt, 01_random_06.txt, 01_random_07.txt, 01_random_08.txt, 01_random_09.txt, 01_random_10.txt, 01_random_11.txt, 01_random_12.txt, 01_random_13.txt, 01_random_14.txt, 01_random_15.txt, 01_random_16.txt, 01_random_17.txt, 01_random_18.txt, 01_random_19.txt, 01_random_20.txt, 01_random_21.txt, 01_random_22.txt, 01_random_23.txt, 01_random_24.txt, 01_random_25.txt, 01_random_26.txt, 01_random_27.txt, 01_random_28.txt, 01_random_29.txt, 01_random_30.txt, 01_random_31.txt, 01_random_32.txt, 01_random_33.txt, 01_random_34.txt, 01_random_35.txt, 01_random_36.txt, 01_random_37.txt, 01_random_38.txt, 01_random_39.txt, 01_random_40.txt, 01_random_41.txt, 01_random_42.txt, 01_random_43.txt, 01_random_44.txt, 01_random_45.txt, 01_random_46.txt, 01_random_47.txt, 01_random_48.txt, 01_random_49.txt, 01_random_50.txt, 01_random_51.txt, 01_random_52.txt, 01_random_53.txt, 01_random_54.txt, 01_random_55.txt
Case Name
Status
Exec Time
Memory
00_sample_00.txt
AC
0 ms
1840 KiB
00_sample_01.txt
AC
0 ms
1940 KiB
00_sample_02.txt
AC
1 ms
2156 KiB
01_random_03.txt
AC
20 ms
27152 KiB
01_random_04.txt
AC
22 ms
28680 KiB
01_random_05.txt
AC
9 ms
16368 KiB
01_random_06.txt
AC
11 ms
15460 KiB
01_random_07.txt
AC
13 ms
22940 KiB
01_random_08.txt
AC
26 ms
42716 KiB
01_random_09.txt
AC
30 ms
42628 KiB
01_random_10.txt
AC
24 ms
42788 KiB
01_random_11.txt
AC
34 ms
42780 KiB
01_random_12.txt
AC
20 ms
42760 KiB
01_random_13.txt
AC
18 ms
42792 KiB
01_random_14.txt
AC
26 ms
42612 KiB
01_random_15.txt
AC
28 ms
42720 KiB
01_random_16.txt
AC
32 ms
42736 KiB
01_random_17.txt
AC
25 ms
42780 KiB
01_random_18.txt
AC
19 ms
42836 KiB
01_random_19.txt
AC
37 ms
42832 KiB
01_random_20.txt
AC
26 ms
42836 KiB
01_random_21.txt
AC
20 ms
42788 KiB
01_random_22.txt
AC
33 ms
42780 KiB
01_random_23.txt
AC
35 ms
42764 KiB
01_random_24.txt
AC
31 ms
42756 KiB
01_random_25.txt
AC
40 ms
42700 KiB
01_random_26.txt
AC
24 ms
42796 KiB
01_random_27.txt
AC
30 ms
42764 KiB
01_random_28.txt
AC
32 ms
42620 KiB
01_random_29.txt
AC
27 ms
42848 KiB
01_random_30.txt
AC
25 ms
42788 KiB
01_random_31.txt
AC
24 ms
42764 KiB
01_random_32.txt
AC
17 ms
42780 KiB
01_random_33.txt
AC
30 ms
42780 KiB
01_random_34.txt
AC
27 ms
42760 KiB
01_random_35.txt
AC
33 ms
42764 KiB
01_random_36.txt
AC
30 ms
42716 KiB
01_random_37.txt
AC
24 ms
42780 KiB
01_random_38.txt
AC
24 ms
42780 KiB
01_random_39.txt
AC
25 ms
42752 KiB
01_random_40.txt
AC
20 ms
38484 KiB
01_random_41.txt
AC
26 ms
34264 KiB
01_random_42.txt
AC
25 ms
36992 KiB
01_random_43.txt
AC
7 ms
14500 KiB
01_random_44.txt
AC
20 ms
31492 KiB
01_random_45.txt
AC
5 ms
9316 KiB
01_random_46.txt
AC
27 ms
36940 KiB
01_random_47.txt
AC
16 ms
21148 KiB
01_random_48.txt
AC
5 ms
14564 KiB
01_random_49.txt
AC
19 ms
28644 KiB
01_random_50.txt
AC
17 ms
35544 KiB
01_random_51.txt
AC
34 ms
42832 KiB
01_random_52.txt
AC
15 ms
42756 KiB
01_random_53.txt
AC
0 ms
1948 KiB
01_random_54.txt
AC
0 ms
1984 KiB
01_random_55.txt
AC
0 ms
1820 KiB