struct Polynomial<M>(Vec<MInt<M>>)
where
M: MIntDotProduct;Tuple Fields§
§0: Vec<MInt<M>>Implementations§
Source§impl<M> Polynomial<M>where
M: MIntDotProduct,
impl<M> Polynomial<M>where
M: MIntDotProduct,
Sourcefn exact_div(self, rhs: &Self) -> Option<Self>
fn exact_div(self, rhs: &Self) -> Option<Self>
Examples found in repository?
crates/competitive/src/math/mint_matrix.rs (line 275)
255fn frobenius_decomposition<M>(
256 a: &Matrix<AddMulOperation<MInt<M>>>,
257 rng: &mut Xorshift,
258) -> Option<FrobeniusDecomposition<M>>
259where
260 M: MIntDotProduct + MIntConvert<u64>,
261{
262 let n = a.shape.0;
263 let mut rows = Vec::with_capacity(n);
264 let mut t = Vec::with_capacity(n);
265 let mut blocks: Vec<Polynomial<M>> = Vec::new();
266 while rows.len() < n {
267 let s = rows.len();
268 let v = (0..n).map(|_| MInt::from(rng.rand64())).collect();
269 let c = generate_frobenius_block(a, v, &mut rows, &mut t);
270 if rows.len() == s {
271 continue;
272 }
273 let p = Polynomial(c.0[s..].to_vec());
274 if c.0[..s].iter().any(|x| !x.is_zero()) {
275 let q = c.exact_div(&p)?;
276 let d = rows.len() - s;
277 let mut coefficients = q.0[..s].to_vec();
278 let mut shifts = Vec::with_capacity(d);
279 for _ in 0..d {
280 shifts.push(coefficients.clone());
281 let mut first = 0;
282 for block in &blocks {
283 let len = block.0.len() - 1;
284 let c = &mut coefficients[first..first + len];
285 let last = c[len - 1];
286 for j in (1..len).rev() {
287 c[j] = c[j - 1] - last * block.0[j];
288 }
289 c[0] = -last * block.0[0];
290 first += len;
291 }
292 }
293 let shifts: Matrix<AddMulOperation<MInt<M>>> = Matrix::from_vec(shifts);
294 if d < 32 {
295 let (previous, current) = t.split_at_mut(s);
296 for (shift, row) in shifts.data.iter().zip(current) {
297 for (factor, source) in shift.iter().zip(previous.iter()) {
298 if !factor.is_zero() {
299 MInt::add_scaled_assign(row, source, factor);
300 }
301 }
302 }
303 } else {
304 let previous = Matrix::from_vec(t[..s].to_vec());
305 let correction = &shifts * &previous;
306 for (row, correction) in t[s..].iter_mut().zip(&correction.data) {
307 for (x, &y) in row.iter_mut().zip(correction) {
308 *x += y;
309 }
310 }
311 }
312 for row in &mut rows[s..] {
313 // Keep the reduced vector fixed: T_new += S*T_old gives C_old -= C_new*S.
314 let (previous, current) = row.row[n..].split_at_mut(s);
315 for (&x, shift) in current.iter().zip(&shifts.data) {
316 MInt::add_scaled_assign(previous, shift, &-x);
317 }
318 }
319 }
320 blocks.push(p);
321 }
322
323 let mut t_inv = vec![vec![MInt::zero(); n]; n];
324 for i in (0..n).rev() {
325 let row = &rows[i];
326 let mut c = row.row[n..].to_vec();
327 c.resize(n, MInt::zero());
328 for x in &mut c {
329 *x *= row.inv;
330 }
331 for next in &rows[i + 1..] {
332 let factor = -row.row[next.pivot] * row.inv;
333 if !factor.is_zero() {
334 MInt::add_scaled_assign(&mut c, &t_inv[next.pivot], &factor);
335 }
336 }
337 t_inv[row.pivot] = c;
338 }
339 Some(FrobeniusDecomposition {
340 t: Matrix::from_vec(t),
341 t_inv: Matrix::from_vec(t_inv),
342 blocks,
343 })
344}Sourcefn square_mod(&self, p: &Self) -> Self
fn square_mod(&self, p: &Self) -> Self
Examples found in repository?
crates/competitive/src/math/mint_matrix.rs (line 242)
234 fn x_pow_mod(&self, k: usize) -> Self {
235 let d = self.0.len() - 1;
236 if d == 1 {
237 return Self(vec![(-self.0[0]).pow(k)]);
238 }
239 let mut r = Self(vec![MInt::zero(); d]);
240 r.0[0] = MInt::one();
241 for bit in (0..usize::BITS - k.leading_zeros()).rev() {
242 r = r.square_mod(self);
243 if k >> bit & 1 != 0 {
244 let x = r.0[d - 1];
245 for i in (1..d).rev() {
246 r.0[i] = r.0[i - 1] - x * self.0[i];
247 }
248 r.0[0] = -x * self.0[0];
249 }
250 }
251 r
252 }Sourcefn x_pow_mod(&self, k: usize) -> Self
fn x_pow_mod(&self, k: usize) -> Self
Examples found in repository?
crates/competitive/src/math/mint_matrix.rs (line 356)
350 fn pow(&self, k: usize) -> Matrix<AddMulOperation<MInt<M>>> {
351 let n = self.t.shape.0;
352 let mut a = vec![vec![MInt::zero(); n]; n];
353 let mut s = 0;
354 for p in &self.blocks {
355 let d = p.0.len() - 1;
356 let mut c = p.x_pow_mod(k).0;
357 for row in &mut a[s..s + d] {
358 row[s..s + d].copy_from_slice(&c);
359 let x = c[d - 1];
360 for i in (1..d).rev() {
361 c[i] = c[i - 1] - x * p.0[i];
362 }
363 c[0] = -x * p.0[0];
364 }
365 s += d;
366 }
367 Matrix::from_vec(a)
368 }Auto Trait Implementations§
impl<M> Freeze for Polynomial<M>
impl<M> RefUnwindSafe for Polynomial<M>
impl<M> Send for Polynomial<M>
impl<M> Sync for Polynomial<M>
impl<M> Unpin for Polynomial<M>
impl<M> UnsafeUnpin for Polynomial<M>
impl<M> UnwindSafe for Polynomial<M>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more