提出 #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 |
| 結果 |
|
|
| セット名 |
テストケース |
| 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 |