QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#237740 | #7686. The Phantom Menace | ucup-team635# | WA | 0ms | 2104kb | Rust | 11.9kb | 2023-11-04 14:51:53 | 2023-11-04 14:51:54 |
Judging History
你现在查看的是最新测评结果
- [2024-10-08 14:11:03]
- hack成功,自动添加数据
- (/hack/941)
- [2024-10-08 10:05:28]
- hack成功,自动添加数据
- (/hack/940)
- [2024-10-07 19:51:15]
- hack成功,自动添加数据
- (/hack/938)
- [2024-10-07 19:28:01]
- hack成功,自动添加数据
- (/hack/937)
- [2024-10-07 17:16:32]
- hack成功,自动添加数据
- (/hack/936)
- [2024-10-07 16:53:09]
- hack成功,自动添加数据
- (/hack/935)
- [2024-10-07 16:22:17]
- hack成功,自动添加数据
- (/hack/934)
- [2023-11-09 15:33:42]
- hack成功,自动添加数据
- (//qoj.ac/hack/445)
- [2023-11-04 14:51:53]
- 提交
answer
//---------- begin union_find ----------
pub struct DSU {
p: Vec<i32>,
}
impl DSU {
pub fn new(n: usize) -> DSU {
assert!(n < std::i32::MAX as usize);
DSU { p: vec![-1; n] }
}
pub fn init(&mut self) {
self.p.iter_mut().for_each(|p| *p = -1);
}
pub fn root(&self, mut x: usize) -> usize {
assert!(x < self.p.len());
while self.p[x] >= 0 {
x = self.p[x] as usize;
}
x
}
pub fn same(&self, x: usize, y: usize) -> bool {
assert!(x < self.p.len() && y < self.p.len());
self.root(x) == self.root(y)
}
pub fn unite(&mut self, x: usize, y: usize) -> Option<(usize, usize)> {
assert!(x < self.p.len() && y < self.p.len());
let mut x = self.root(x);
let mut y = self.root(y);
if x == y {
return None;
}
if self.p[x] > self.p[y] {
std::mem::swap(&mut x, &mut y);
}
self.p[x] += self.p[y];
self.p[y] = x as i32;
Some((x, y))
}
pub fn parent(&self, x: usize) -> Option<usize> {
assert!(x < self.p.len());
let p = self.p[x];
if p >= 0 {
Some(p as usize)
} else {
None
}
}
pub fn sum<F>(&self, mut x: usize, mut f: F) -> usize
where
F: FnMut(usize),
{
while let Some(p) = self.parent(x) {
f(x);
x = p;
}
x
}
pub fn size(&self, x: usize) -> usize {
assert!(x < self.p.len());
let r = self.root(x);
(-self.p[r]) as usize
}
}
//---------- end union_find ----------
mod util {
pub trait Join {
fn join(self, sep: &str) -> String;
}
impl<T, I> Join for I
where
I: Iterator<Item = T>,
T: std::fmt::Display,
{
fn join(self, sep: &str) -> String {
let mut s = String::new();
use std::fmt::*;
for (i, v) in self.enumerate() {
if i > 0 {
write!(&mut s, "{}", sep).ok();
}
write!(&mut s, "{}", v).ok();
}
s
}
}
}
// ---------- begin mod vector ----------
mod modvector {
const MOD: u64 = (1u64 << 61) - 1;
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
struct ModInt(u64);
impl std::ops::Add for ModInt {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
assert!(self.0 < MOD && rhs.0 < MOD);
let mut d = self.0 + rhs.0;
if d >= MOD {
d -= MOD;
}
ModInt(d)
}
}
impl std::ops::Sub for ModInt {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
assert!(self.0 < MOD && rhs.0 < MOD);
let mut d = self.0 + MOD - rhs.0;
if d >= MOD {
d -= MOD;
}
ModInt(d)
}
}
impl std::ops::Mul for ModInt {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
assert!(self.0 < MOD && rhs.0 < MOD);
const MASK31: u64 = (1u64 << 31) - 1;
const MASK30: u64 = (1u64 << 30) - 1;
let au = self.0 >> 31;
let ad = self.0 & MASK31;
let bu = rhs.0 >> 31;
let bd = rhs.0 & MASK31;
let mid = ad * bu + au * bd;
let midu = mid >> 30;
let midd = mid & MASK30;
let sum = au * bu * 2 + midu + (midd << 31) + ad * bd;
let mut ans = (sum >> 61) + (sum & MOD);
if ans >= MOD {
ans -= MOD;
}
ModInt(ans)
}
}
impl ModInt {
fn new(v: u64) -> Self {
ModInt(v % MOD)
}
fn zero() -> Self {
ModInt(0)
}
fn pow(&self, n: u64) -> Self {
let mut t = ModInt(1);
let mut s = *self;
let mut n = n;
while n > 0 {
if n & 1 == 1 {
t = t * s;
}
s = s * s;
n >>= 1;
}
t
}
fn inv(&self) -> Self {
assert!(self.0 > 0);
self.pow(MOD - 2)
}
}
pub const BASE_NUM: usize = 2;
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ModVector {
val: [ModInt; BASE_NUM],
}
#[allow(dead_code)]
impl ModVector {
pub fn zero() -> Self {
ModVector {
val: [ModInt::zero(); BASE_NUM],
}
}
pub fn new(v: &[u64]) -> Self {
assert!(v.len() >= BASE_NUM);
let mut ans = ModVector::zero();
for (x, a) in ans.val.iter_mut().zip(v.iter()) {
*x = ModInt::new(*a);
}
ans
}
pub fn single(v: u64) -> Self {
ModVector::new(&[v; BASE_NUM])
}
pub fn add(&self, rhs: &Self) -> Self {
let mut ans = ModVector::zero();
for (c, (a, b)) in ans.val.iter_mut().zip(self.val.iter().zip(rhs.val.iter())) {
*c = *a + *b;
}
ans
}
pub fn sub(&self, rhs: &Self) -> Self {
let mut ans = ModVector::zero();
for (c, (a, b)) in ans.val.iter_mut().zip(self.val.iter().zip(rhs.val.iter())) {
*c = *a - *b;
}
ans
}
pub fn mul(&self, rhs: &Self) -> Self {
let mut ans = ModVector::zero();
for (c, (a, b)) in ans.val.iter_mut().zip(self.val.iter().zip(rhs.val.iter())) {
*c = *a * *b;
}
ans
}
pub fn inv(&self) -> Self {
let mut ans = ModVector::zero();
for (x, a) in ans.val.iter_mut().zip(self.val.iter()) {
*x = a.inv();
}
ans
}
}
pub fn rand_time() -> u32 {
static mut X: u32 = 0;
unsafe {
if X == 0 {
use std::time::{SystemTime, UNIX_EPOCH};
X = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.subsec_nanos();
}
X ^= X << 13;
X ^= X >> 17;
X ^= X << 5;
X
}
}
pub fn rand_memory() -> u32 {
static mut X: u32 = 0;
unsafe {
if X == 0 {
X = Box::into_raw(Box::new("I hope this is a random number")) as u32;
}
X ^= X << 13;
X ^= X >> 17;
X ^= X << 5;
X
}
}
pub fn generate_random_rad() -> ModVector {
let mut rad = ModVector::zero();
for (i, v) in rad.val.iter_mut().enumerate() {
*v = ModInt::new(if i & 1 == 0 {
rand_time() as u64 + 2
} else {
rand_memory() as u64 + 2
});
}
rad
}
}
// ---------- end mod vector ----------
// ---------- begin scannner ----------
#[allow(dead_code)]
mod scanner {
use std::str::FromStr;
pub struct Scanner<'a> {
it: std::str::SplitWhitespace<'a>,
}
impl<'a> Scanner<'a> {
pub fn new(s: &'a String) -> Scanner<'a> {
Scanner {
it: s.split_whitespace(),
}
}
pub fn next<T: FromStr>(&mut self) -> T {
self.it.next().unwrap().parse::<T>().ok().unwrap()
}
pub fn next_bytes(&mut self) -> Vec<u8> {
self.it.next().unwrap().bytes().collect()
}
pub fn next_chars(&mut self) -> Vec<char> {
self.it.next().unwrap().chars().collect()
}
pub fn next_vec<T: FromStr>(&mut self, len: usize) -> Vec<T> {
(0..len).map(|_| self.next()).collect()
}
}
}
// ---------- end scannner ----------
use std::collections::*;
use std::io::Write;
type Map<K, V> = BTreeMap<K, V>;
type Set<T> = BTreeSet<T>;
type Deque<T> = VecDeque<T>;
fn main() {
use std::io::Read;
let mut s = String::new();
std::io::stdin().read_to_string(&mut s).unwrap();
let mut sc = scanner::Scanner::new(&s);
let out = std::io::stdout();
let mut out = std::io::BufWriter::new(out.lock());
run(&mut sc, &mut out);
}
fn run<W: Write>(sc: &mut scanner::Scanner, out: &mut std::io::BufWriter<W>) {
let t: u32 = sc.next();
for _ in 0..t {
let n: usize = sc.next();
let m: usize = sc.next();
let a = (0..n).map(|_| sc.next_bytes()).collect::<Vec<_>>();
let b = (0..n).map(|_| sc.next_bytes()).collect::<Vec<_>>();
if let Some((p, q)) = solve(a, b) {
use util::*;
writeln!(out, "{}", p.iter().join(" ")).ok();
writeln!(out, "{}", q.iter().join(" ")).ok();
} else {
writeln!(out, "-1").ok();
}
}
}
use modvector::*;
type M = ModVector;
fn solve(a: Vec<Vec<u8>>, b: Vec<Vec<u8>>) -> Option<(Vec<usize>, Vec<usize>)> {
let rad = generate_random_rad();
let n = a.len();
let m = a[0].len();
let mut x = vec![];
for a in a {
let mut table = vec![M::zero(); m + 1];
for (i, a) in a.iter().enumerate().rev() {
table[i] = table[i + 1].mul(&rad).add(&M::single(*a as u64));
}
x.push(table);
}
let x = x;
let mut y = vec![];
for a in b {
let mut table = vec![M::zero(); m + 1];
for (i, a) in a.iter().enumerate().rev() {
table[i] = table[i + 1].mul(&rad).add(&M::single(*a as u64));
}
y.push(table);
}
let y = y;
let mut pow = vec![M::single(1); m + 1];
for i in 1..=m {
pow[i] = pow[i - 1].mul(&rad);
}
for d in 0..m {
let mut map = Map::new();
let mut get_id = |val: (M, usize)| -> usize {
if let Some(&v) = map.get(&val) {
return v;
}
let id = map.len();
map.insert(val, id);
id
};
let find = |l: usize, r: usize, x: &[M]| -> M {
x[l].sub(&x[r].mul(&pow[r - l]))
};
let mut g = vec![];
let mut deg = vec![0; 4 * n];
for (i, x) in x.iter().enumerate() {
let s = find(0, d, x);
let t = find(d, m, x);
let s = get_id((s, 0));
let t = get_id((t, 1));
if s >= g.len() {
g.push(vec![]);
}
if t >= g.len() {
g.push(vec![]);
}
g[s].push((t, i));
deg[s] += 1;
deg[t] -= 1;
}
for (i, y) in y.iter().enumerate() {
let s = find(0, m - d, y);
let t = find(m - d, m, y);
let s = get_id((s, 1));
let t = get_id((t, 0));
if s >= g.len() {
g.push(vec![]);
}
if t >= g.len() {
g.push(vec![]);
}
g[s].push((t, i));
deg[s] += 1;
deg[t] -= 1;
}
let mut ans = vec![];
dfs(0, &mut g, &mut ans);
if ans.len() == 2 * n && deg.iter().all(|d| *d == 0) {
let p = ans[1..].iter().step_by(2).map(|a| *a + 1).collect();
let q = ans.iter().step_by(2).map(|a| *a + 1).collect();
return Some((p, q));
}
}
None
}
fn dfs(v: usize, g: &mut [Vec<(usize, usize)>], ans: &mut Vec<usize>) {
while let Some((t, k)) = g[v].pop() {
dfs(t, g, ans);
ans.push(k);
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 0ms
memory: 2104kb
input:
2 3 3 abc ghi def bcd efg hia 1 3 abc def
output:
2 3 1 3 2 1 -1
result:
wrong answer not cyclic isomorphism (test case 1)