提出 #70618174


ソースコード 拡げる

#![allow(unused_parens)]
#![allow(unused_imports)]
#![allow(non_upper_case_globals)]
#![allow(non_snake_case)]
#![allow(unused_mut)]
#![allow(unused_variables)]
#![allow(dead_code)]
#![allow(unused_macros)]

use itertools::Itertools;
use proconio::input;
use proconio::marker::{Chars, Usize1};

type Vec2<T> = Vec<Vec<T>>;
type Vec3<T> = Vec<Vec<Vec<T>>>;
#[rustfmt::skip]
macro_rules ! max { ( $x : expr ) => ( $x ) ; ( $x : expr , $ ( $xs : expr ) ,+ ) => { {  std :: cmp :: max ( $x , max! ( $ ( $xs ) ,+ ) ) } } ; }
#[rustfmt::skip]
macro_rules ! min { ( $x : expr ) => ( $x ) ; ( $x : expr , $ ( $xs : expr ) ,+ ) => { {  std :: cmp :: min ( $x , min! ( $ ( $xs ) ,+ ) ) } } ; }
#[rustfmt::skip]
macro_rules! chmin {    ($a:expr, $($b:expr),+) => {{        let d = min!($($b),+);        if $a > d {            $a = d;            true        } else {            false        }    }}; }

#[rustfmt::skip]
macro_rules! chmax {    ($a:expr, $($b:expr),+) => {{        let d = max!($($b),+);        if $a < d {            $a = d;            true        } else {            false        }    }};}

#[rustfmt::skip]
macro_rules! chadd {    ($a:expr, $b:expr) => {{        $a = $a + $b;    }};}
#[rustfmt::skip]
macro_rules! chsub {    ($a:expr, $b:expr) => {{        $a = $a - $b;    }};}
#[rustfmt::skip]
macro_rules! chmul {    ($a:expr, $b:expr) => {{        $a = $a * $b;    }};}

#[cfg(debug_assertions)]
macro_rules! mydbg {
    //($arg:expr) => (dbg!($arg))
    //($arg:expr) => (println!("{:?}",$arg));
      ($($a:expr),*) => {
          eprintln!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
      }
}
#[cfg(not(debug_assertions))]
macro_rules! mydbg {
    ($($arg:expr),*) => {};
}

macro_rules! echo {
    ($($a:expr),*) => {
          $(println!("{}",$a))*
      }
}

macro_rules! multivec {
    ($a:expr;$b:expr) => {
        vec![$a; $b]
    };
    ($a:expr;$b:expr;$($c:expr);+) => {
        multivec![vec![$a;$b];$($c);+]
    };
}

use std::cmp::*;
use std::collections::*;
use std::ops::{Add, Div, Mul, Rem, Sub};

fn echoNoReturn() {
    echo!("No");
    std::process::exit(0);
}
fn echoYesReturn() {
    echo!("Yes");
    std::process::exit(0);
}

fn echoNo() {
    echo!("No");
}
fn echoYes() {
    echo!("Yes");
}

#[allow(dead_code)]
static INF_I64: i64 = 92233720368547758;
#[allow(dead_code)]
static INF_I32: i32 = 21474836;
#[allow(dead_code)]
static INF_USIZE: usize = 18446744073709551;
#[allow(dead_code)]
static M_O_D: usize = 1000000007;
#[allow(dead_code)]
static PAI: f64 = 3.1415926535897932;

trait IteratorExt: Iterator {
    fn toVec(self) -> Vec<Self::Item>;
}

impl<T: Iterator> IteratorExt for T {
    fn toVec(self) -> Vec<Self::Item> {
        self.collect()
    }
}

fn sin(a: f64) -> f64 {
    a.sin()
}
fn cos(a: f64) -> f64 {
    a.cos()
}
trait ToNum {
    fn toNum(&self) -> Vec<usize>;
}
impl ToNum for Vec<char> {
    fn toNum(&self) -> Vec<usize> {
        if self[0].is_ascii_digit() {
            self.iter().map(|x| x.toNumIndex()).toVec()
        } else {
            self.iter().map(|x| x.toAlphabetIndex()).toVec()
        }
    }
}

trait CharExt {
    fn toNum(&self) -> usize;
    fn toAlphabetIndex(&self) -> usize;
    fn toNumIndex(&self) -> usize;
}
impl CharExt for char {
    fn toNum(&self) -> usize {
        return *self as usize;
    }
    fn toAlphabetIndex(&self) -> usize {
        return self.toNum() - 'a' as usize;
    }
    fn toNumIndex(&self) -> usize {
        return self.toNum() - '0' as usize;
    }
}
trait PrimeNumber:
    Copy
    + Ord
    + Add<Output = Self>
    + Sub<Output = Self>
    + Mul<Output = Self>
    + Div<Output = Self>
    + Rem<Output = Self>
{
    fn is_odd(self) -> bool;
    fn is_even(self) -> bool;
    fn pow(self, exp: u32) -> Self;
}

macro_rules! impl_prim_int(($($ty:ty),*) => {
    $(
        impl PrimeNumber for $ty {
            fn pow(self, exp: u32) -> Self {
                self.pow(exp)
            }
            fn is_odd(self)->bool{
                self & 1==1
            }

            fn is_even(self)->bool{
                self & 1==0
            }
        }
    )*
});

trait SafeRangeContain {
    fn safe_contains(&self, x: i64) -> bool;
}

impl SafeRangeContain for std::ops::Range<usize> {
    fn safe_contains(&self, x: i64) -> bool {
        if x < 0 {
            return false;
        }
        return self.contains(&(x as usize));
    }
}

impl_prim_int!(
    u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
);
trait VectorExt {
    fn joinToString(&self, s: &str) -> String;
}
impl<T: ToString> VectorExt for Vec<T> {
    fn joinToString(&self, s: &str) -> String {
        return self
            .iter()
            .map(|x| x.to_string())
            .collect::<Vec<_>>()
            .join(s);
    }
}

trait StringExt {
    fn get_reverse(&self) -> String;
}
impl StringExt for String {
    fn get_reverse(&self) -> String {
        self.chars().rev().collect::<String>()
    }
}

trait UsizeExt {
    fn pow(&self, n: usize) -> usize;
}
impl UsizeExt for usize {
    fn pow(&self, n: usize) -> usize {
        return ((*self as u64).pow(n as u32)) as usize;
    }
}

use itertools_num::ItertoolsNum as _;
use superslice::*;

/// 回文の判定ではそのままと反転の2つのrollinghashを作る
/// 範囲は半開区間
pub struct RollingHash {
    hash1: Vec<i64>,
    hash2: Vec<i64>,
    p1: Vec<i64>,
    p2: Vec<i64>,
    b1: i64,
    b2: i64,
    mod1: i64,
    mod2: i64,
    chars: Vec<char>,
    length: usize,
}
impl RollingHash {
    pub fn new(s: String) -> Self {
        let n = s.len();
        let chars = s.chars().collect::<Vec<char>>();
        RollingHash {
            hash1: vec![0; n + 1],
            hash2: vec![0; n + 1],
            p1: vec![1; n + 1],
            p2: vec![1; n + 1],
            b1: 1234_i64,
            b2: 2019_i64,
            mod1: 1000000007_i64,
            mod2: 1000000009_i64,
            chars: chars,
            length: n,
        }
    }
    pub fn init(&mut self) {
        for i in 0..self.length {
            self.hash1[i + 1] = (self.hash1[i] * self.b1 + self.chars[i] as i64) % self.mod1;
            self.hash2[i + 1] = (self.hash2[i] * self.b2 + self.chars[i] as i64) % self.mod2;
            self.p1[i + 1] = (self.p1[i] * self.b1) % self.mod1;
            self.p2[i + 1] = (self.p2[i] * self.b2) % self.mod2;
        }
    }
    pub fn get(&mut self, l: usize, r: usize) -> (i64, i64) {
        let a = self.hash1[r];
        let b = self.hash1[l] * self.p1[r - l];
        let mut h1: i64 = a - b % self.mod1;
        if h1 < 0 {
            h1 += self.mod1
        }
        let a = self.hash2[r];
        let b = self.hash2[l] * self.p2[r - l];
        let mut h2: i64 = a - b % self.mod2;
        if h2 < 0 {
            h2 += self.mod2
        }
        return (h1, h2);
    }
    pub fn possible(&mut self, m: usize) -> bool {
        let mut cache: HashMap<(i64, i64), usize> = HashMap::new();
        for i in 0..(self.length - m + 1) {
            let target = self.get(i, i + m);
            if (cache.contains_key(&target)) {
                if (cache.get(&target).unwrap() + m <= i) {
                    return true;
                }
            } else {
                cache.insert(target, i);
            }
        }
        return false;
    }
}

fn main() {
    input! {
       T: usize,
    }

    for _ in 0..T {
        solve();
    }
}

fn solve() {
    input! {
        A:Chars,
        B:Chars,
    }
    let mut a = vec![];
    for &item in &A {
        a.push(item);
    }
    for &item in &A {
        a.push(item);
    }
    for &item in &B {
        a.push(item);
    }

    let N = A.len();
    mydbg!(N, a);
    mydbg!(N);
    let mut r = RollingHash::new(a.joinToString(""));
    r.init();
    let mut ans = A.len() * 2;
    let h = r.get(N * 2, N * 3);
    mydbg!(h);

    for i in 0..A.len() {
        let h2 = r.get(i, i + N);
        if h == h2 {
            echo!(i);
            return;
        }
    }

    echo!(-1);
}

提出情報

提出日時
問題 E - Shift String
ユーザ bqn
言語 Rust (rustc 1.89.0)
得点 450
コード長 8338 Byte
結果 AC
実行時間 240 ms
メモリ 189508 KiB

ジャッジ結果

セット名 Sample All
得点 / 配点 0 / 0 450 / 450
結果
AC × 1
AC × 52
セット名 テストケース
Sample sample_01.txt
All killer_01.txt, sample_01.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
ケース名 結果 実行時間 メモリ
killer_01.txt AC 82 ms 2012 KiB
sample_01.txt AC 1 ms 2236 KiB
test_01.txt AC 1 ms 1948 KiB
test_02.txt AC 1 ms 1920 KiB
test_03.txt AC 1 ms 2100 KiB
test_04.txt AC 1 ms 2040 KiB
test_05.txt AC 2 ms 2084 KiB
test_06.txt AC 7 ms 2096 KiB
test_07.txt AC 7 ms 2064 KiB
test_08.txt AC 151 ms 2040 KiB
test_09.txt AC 142 ms 2064 KiB
test_10.txt AC 156 ms 2352 KiB
test_11.txt AC 154 ms 2296 KiB
test_12.txt AC 176 ms 3828 KiB
test_13.txt AC 176 ms 3804 KiB
test_14.txt AC 184 ms 21648 KiB
test_15.txt AC 183 ms 21560 KiB
test_16.txt AC 235 ms 189392 KiB
test_17.txt AC 235 ms 189460 KiB
test_18.txt AC 229 ms 189320 KiB
test_19.txt AC 230 ms 189368 KiB
test_20.txt AC 230 ms 189324 KiB
test_21.txt AC 232 ms 189408 KiB
test_22.txt AC 232 ms 189364 KiB
test_23.txt AC 231 ms 189428 KiB
test_24.txt AC 231 ms 189372 KiB
test_25.txt AC 232 ms 189380 KiB
test_26.txt AC 232 ms 189404 KiB
test_27.txt AC 234 ms 189388 KiB
test_28.txt AC 238 ms 189276 KiB
test_29.txt AC 239 ms 189380 KiB
test_30.txt AC 237 ms 189312 KiB
test_31.txt AC 238 ms 189372 KiB
test_32.txt AC 239 ms 189372 KiB
test_33.txt AC 239 ms 189344 KiB
test_34.txt AC 239 ms 189376 KiB
test_35.txt AC 237 ms 189368 KiB
test_36.txt AC 240 ms 189372 KiB
test_37.txt AC 239 ms 189508 KiB
test_38.txt AC 239 ms 189340 KiB
test_39.txt AC 239 ms 189368 KiB
test_40.txt AC 238 ms 189368 KiB
test_41.txt AC 239 ms 189476 KiB
test_42.txt AC 237 ms 189296 KiB
test_43.txt AC 231 ms 189432 KiB
test_44.txt AC 237 ms 189388 KiB
test_45.txt AC 234 ms 189340 KiB
test_46.txt AC 233 ms 189380 KiB
test_47.txt AC 20 ms 2040 KiB
test_48.txt AC 21 ms 2156 KiB
test_49.txt AC 235 ms 189420 KiB
test_50.txt AC 236 ms 189468 KiB