結果

問題 No.1548 [Cherry 2nd Tune B] 貴方と私とサイクルとモーメント
ユーザー akakimidori
提出日時 2021-06-11 22:59:15
言語 Rust
(1.83.0 + proconio)
結果
AC  
実行時間 108 ms / 4,500 ms
コード長 14,195 bytes
コンパイル時間 14,987 ms
コンパイル使用メモリ 377,212 KB
実行使用メモリ 22,912 KB
最終ジャッジ日時 2024-12-15 01:50:17
合計ジャッジ時間 19,880 ms
ジャッジサーバーID
(参考情報)
judge3 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 42
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

// ---------- begin Lazy Segment Tree ----------
pub trait TE {
type T: Clone;
type E: Clone;
fn fold(l: &Self::T, r: &Self::T) -> Self::T;
fn eval(x: &Self::T, f: &Self::E) -> Self::T;
fn merge(g: &Self::E, h: &Self::E) -> Self::E;
fn e() -> Self::T;
fn id() -> Self::E;
}
pub struct LazySegmentTree<R: TE> {
size: usize,
bit: usize,
a: Vec<(R::T, R::E)>,
}
impl<R: TE> LazySegmentTree<R> {
pub fn new(n: usize) -> LazySegmentTree<R> {
let size = n.next_power_of_two();
let bit = size.trailing_zeros() as usize;
LazySegmentTree {
size: size,
bit: bit,
a: vec![(R::e(), R::id()); 2 * size],
}
}
pub fn build_by(z: &[R::T]) -> LazySegmentTree<R> {
let mut seg = LazySegmentTree::<R>::new(z.len());
for (a, z) in seg.a[seg.size..].iter_mut().zip(z.iter()) {
a.0 = z.clone();
}
let a = &mut seg.a;
for i in (1..seg.size).rev() {
a[i].0 = R::fold(&a[2 * i].0, &a[2 * i + 1].0);
}
seg
}
fn apply(&mut self, x: usize, op: &R::E) {
let node = &mut self.a[x];
node.0 = R::eval(&node.0, op);
node.1 = R::merge(&node.1, op);
}
fn propagate(&mut self, x: usize) {
let mut op = R::id();
std::mem::swap(&mut op, &mut self.a[x].1);
self.apply(2 * x, &op);
self.apply(2 * x + 1, &op);
}
fn propagate_range(&mut self, l: usize, r: usize) {
let x = l + self.size;
let y = r + self.size;
let mut k = self.bit;
while (x >> k) == (y >> k) {
self.propagate(x >> k);
k -= 1;
}
for i in ((x.trailing_zeros() as usize + 1)..=k).rev() {
self.propagate(x >> i);
}
for i in ((y.trailing_zeros() as usize + 1)..=k).rev() {
self.propagate(y >> i);
}
}
fn save_range(&mut self, l: usize, r: usize) {
let mut x = l + self.size;
let mut y = r + self.size;
let mut p = (x & 1) == 1;
let mut q = (y & 1) == 1;
x >>= 1;
y >>= 1;
while 0 < x && x < y {
if p {
self.a[x].0 = R::fold(&self.a[2 * x].0, &self.a[2 * x + 1].0);
}
if q {
self.a[y].0 = R::fold(&self.a[2 * y].0, &self.a[2 * y + 1].0);
}
p |= (x & 1) == 1;
q |= (y & 1) == 1;
x >>= 1;
y >>= 1;
}
while 0 < x {
self.a[x].0 = R::fold(&self.a[2 * x].0, &self.a[2 * x + 1].0);
x >>= 1;
}
}
pub fn update(&mut self, l: usize, r: usize, op: R::E) {
self.propagate_range(l, r);
let mut x = l + self.size;
let mut y = r + self.size;
while x < y {
if x & 1 == 1 {
self.apply(x, &op);
x += 1;
}
if y & 1 == 1 {
y -= 1;
self.apply(y, &op);
}
x >>= 1;
y >>= 1;
}
self.save_range(l, r);
}
pub fn find(&mut self, l: usize, r: usize) -> R::T {
self.propagate_range(l, r);
let mut x = l + self.size;
let mut y = r + self.size;
let mut p = R::e();
let mut q = R::e();
while x < y {
if x & 1 == 1 {
p = R::fold(&p, &self.a[x].0);
x += 1;
}
if y & 1 == 1 {
y -= 1;
q = R::fold(&self.a[y].0, &q);
}
x >>= 1;
y >>= 1;
}
R::fold(&p, &q)
}
}
// ---------- end Lazy Segment Tree ----------
// ---------- begin ModInt ----------
mod modint {
#[allow(dead_code)]
pub struct Mod;
impl ConstantModulo for Mod {
const MOD: u32 = 998_244_353;
}
#[allow(dead_code)]
pub struct StaticMod;
static mut STATIC_MOD: u32 = 0;
impl Modulo for StaticMod {
fn modulo() -> u32 {
unsafe { STATIC_MOD }
}
}
#[allow(dead_code)]
impl StaticMod {
pub fn set_modulo(p: u32) {
unsafe {
STATIC_MOD = p;
}
}
}
use std::marker::*;
use std::ops::*;
pub trait Modulo {
fn modulo() -> u32;
}
pub trait ConstantModulo {
const MOD: u32;
}
impl<T> Modulo for T
where
T: ConstantModulo,
{
fn modulo() -> u32 {
T::MOD
}
}
pub struct ModInt<T>(pub u32, PhantomData<T>);
impl<T> Clone for ModInt<T> {
fn clone(&self) -> Self {
ModInt::new_unchecked(self.0)
}
}
impl<T> Copy for ModInt<T> {}
impl<T: Modulo> Add for ModInt<T> {
type Output = ModInt<T>;
fn add(self, rhs: Self) -> Self::Output {
let mut d = self.0 + rhs.0;
if d >= T::modulo() {
d -= T::modulo();
}
ModInt::new_unchecked(d)
}
}
impl<T: Modulo> AddAssign for ModInt<T> {
fn add_assign(&mut self, rhs: Self) {
*self = *self + rhs;
}
}
impl<T: Modulo> Sub for ModInt<T> {
type Output = ModInt<T>;
fn sub(self, rhs: Self) -> Self::Output {
let mut d = T::modulo() + self.0 - rhs.0;
if d >= T::modulo() {
d -= T::modulo();
}
ModInt::new_unchecked(d)
}
}
impl<T: Modulo> SubAssign for ModInt<T> {
fn sub_assign(&mut self, rhs: Self) {
*self = *self - rhs;
}
}
impl<T: Modulo> Mul for ModInt<T> {
type Output = ModInt<T>;
fn mul(self, rhs: Self) -> Self::Output {
let v = self.0 as u64 * rhs.0 as u64 % T::modulo() as u64;
ModInt::new_unchecked(v as u32)
}
}
impl<T: Modulo> MulAssign for ModInt<T> {
fn mul_assign(&mut self, rhs: Self) {
*self = *self * rhs;
}
}
impl<T: Modulo> Neg for ModInt<T> {
type Output = ModInt<T>;
fn neg(self) -> Self::Output {
if self.0 == 0 {
Self::zero()
} else {
Self::new_unchecked(T::modulo() - self.0)
}
}
}
impl<T> std::fmt::Display for ModInt<T> {
fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl<T> std::fmt::Debug for ModInt<T> {
fn fmt<'a>(&self, f: &mut std::fmt::Formatter<'a>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl<T: Modulo> std::str::FromStr for ModInt<T> {
type Err = std::num::ParseIntError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let val = s.parse::<u32>()?;
Ok(ModInt::new(val))
}
}
impl<T: Modulo> From<usize> for ModInt<T> {
fn from(val: usize) -> ModInt<T> {
ModInt::new_unchecked((val % T::modulo() as usize) as u32)
}
}
impl<T: Modulo> From<u64> for ModInt<T> {
fn from(val: u64) -> ModInt<T> {
ModInt::new_unchecked((val % T::modulo() as u64) as u32)
}
}
impl<T: Modulo> From<i64> for ModInt<T> {
fn from(val: i64) -> ModInt<T> {
let m = T::modulo() as i64;
ModInt::new((val % m + m) as u32)
}
}
#[allow(dead_code)]
impl<T> ModInt<T> {
pub fn new_unchecked(d: u32) -> Self {
ModInt(d, PhantomData)
}
pub fn zero() -> Self {
ModInt::new_unchecked(0)
}
pub fn one() -> Self {
ModInt::new_unchecked(1)
}
pub fn is_zero(&self) -> bool {
self.0 == 0
}
}
#[allow(dead_code)]
impl<T: Modulo> ModInt<T> {
pub fn new(d: u32) -> Self {
ModInt::new_unchecked(d % T::modulo())
}
pub fn pow(&self, mut n: u64) -> Self {
let mut t = Self::one();
let mut s = *self;
while n > 0 {
if n & 1 == 1 {
t *= s;
}
s *= s;
n >>= 1;
}
t
}
pub fn inv(&self) -> Self {
assert!(self.0 != 0);
self.pow(T::modulo() as u64 - 2)
}
}
}
// ---------- end ModInt ----------
// ---------- begin Precalc ----------
mod precalc {
use super::modint::*;
#[allow(dead_code)]
pub struct Precalc<T> {
inv: Vec<ModInt<T>>,
fact: Vec<ModInt<T>>,
ifact: Vec<ModInt<T>>,
}
#[allow(dead_code)]
impl<T: Modulo> Precalc<T> {
pub fn new(n: usize) -> Precalc<T> {
let mut inv = vec![ModInt::one(); n + 1];
let mut fact = vec![ModInt::one(); n + 1];
let mut ifact = vec![ModInt::one(); n + 1];
for i in 2..(n + 1) {
fact[i] = fact[i - 1] * ModInt::new_unchecked(i as u32);
}
ifact[n] = fact[n].inv();
if n > 0 {
inv[n] = ifact[n] * fact[n - 1];
}
for i in (1..n).rev() {
ifact[i] = ifact[i + 1] * ModInt::new_unchecked((i + 1) as u32);
inv[i] = ifact[i] * fact[i - 1];
}
Precalc {
inv: inv,
fact: fact,
ifact: ifact,
}
}
pub fn inv(&self, n: usize) -> ModInt<T> {
assert!(n > 0);
self.inv[n]
}
pub fn fact(&self, n: usize) -> ModInt<T> {
self.fact[n]
}
pub fn ifact(&self, n: usize) -> ModInt<T> {
self.ifact[n]
}
pub fn perm(&self, n: usize, k: usize) -> ModInt<T> {
if k > n {
return ModInt::zero();
}
self.fact[n] * self.ifact[n - k]
}
pub fn comb(&self, n: usize, k: usize) -> ModInt<T> {
if k > n {
return ModInt::zero();
}
self.fact[n] * self.ifact[k] * self.ifact[n - k]
}
}
}
// ---------- end Precalc ----------
use modint::*;
type M = ModInt<Mod>;
// ---------- 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::io::Write;
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);
}
struct R;
impl TE for R {
// 0, 1, 2, 3, 4
type T = (M, M, M, M, M);
type E = Option<M>;
fn fold(l: &Self::T, r: &Self::T) -> Self::T {
(l.0 + r.0, l.1 + r.1, l.2 + r.2, l.3 + r.3, l.4 + r.4)
}
fn eval(x: &Self::T, f: &Self::E) -> Self::T {
if let Some(f) = *f {
(
x.0,
f * x.0,
f * f * x.0,
f * f * f * x.0,
f * f * f * f * x.0,
)
} else {
*x
}
}
fn merge(g: &Self::E, h: &Self::E) -> Self::E {
if h.is_some() {
*h
} else {
*g
}
}
fn e() -> Self::T {
(M::zero(), M::zero(), M::zero(), M::zero(), M::zero())
}
fn id() -> Self::E {
None
}
}
fn run<W: Write>(sc: &mut scanner::Scanner, out: &mut std::io::BufWriter<W>) {
let n: usize = sc.next();
let mut seg =
LazySegmentTree::<R>::build_by(&vec![
(M::one(), M::zero(), M::zero(), M::zero(), M::zero());
n
]);
for i in 0..n {
let a = sc.next::<u32>();
seg.update(i, i + 1, Some(M::new(a)));
}
let q: usize = sc.next();
for _ in 0..q {
let op: u8 = sc.next();
let mut s = sc.next::<usize>() - 1;
let mut t = sc.next::<usize>() - 1;
if s > t {
std::mem::swap(&mut s, &mut t);
}
let w = sc.next::<usize>() - 1;
if op == 0 {
let b: u32 = sc.next();
let b = M::new(b);
if s < w && w < t {
seg.update(s, t + 1, Some(b));
} else {
seg.update(0, s + 1, Some(b));
seg.update(t, n, Some(b));
}
} else {
let val = if s < w && w < t {
seg.find(s, t + 1)
} else {
let a = seg.find(0, s + 1);
let b = seg.find(t, n);
R::fold(&a, &b)
};
let il = val.0.inv();
let m = val.1 * il;
let ans = il
* if op == 1 {
M::zero()
} else if op == 2 {
val.2 - M::new(2) * val.1 * m + val.0 * m * m
} else if op == 3 {
val.3 - M::new(3) * val.2 * m + M::new(3) * val.1 * m * m - val.0 * m * m * m
} else {
val.4 - M::new(4) * val.3 * m + M::new(6) * val.2 * m * m
- M::new(4) * val.1 * m * m * m
+ val.0 * m * m * m * m
};
writeln!(out, "{}", ans).ok();
}
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0