結果

問題 No.3371 Add Insert Operations
コンテスト
ユーザー rhoo
提出日時 2025-10-29 17:44:24
言語 Rust
(1.83.0 + proconio)
結果
WA  
実行時間 -
コード長 12,240 bytes
コンパイル時間 13,370 ms
コンパイル使用メモリ 399,824 KB
実行使用メモリ 8,900 KB
最終ジャッジ日時 2025-11-17 20:38:34
合計ジャッジ時間 18,399 ms
ジャッジサーバーID
(参考情報)
judge5 / judge4
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 6 WA * 2 TLE * 1 -- * 27
権限があれば一括ダウンロードができます
コンパイルメッセージ
warning: fields `n`, `size`, and `a` are never read
   --> src/main.rs:100:5
    |
99  | struct Segtree<M:Monoid>{
    |        ------- fields in this struct
100 |     n:usize,
    |     ^
101 |     size:usize,
    |     ^^^^
102 |     a:Vec<M::S>,
    |     ^
    |
    = note: `Segtree` has a derived impl for the trait `Clone`, but this is intentionally ignored during dead code analysis
    = note: `#[warn(dead_code)]` on by default

warning: associated items `new`, `set`, `get`, `prod`, `max_right`, and `min_left` are never used
   --> src/main.rs:118:8
    |
117 | impl<M:Monoid> Segtree<M>{
    | ------------------------- associated items in this implementation
118 |     fn new(n:usize)->Self{
    |        ^^^
...
126 |     fn set(&mut self,mut i:usize,v:M::S){
    |        ^^^
...
137 |     fn get(&self,i:usize)->M::S{
    |        ^^^
...
142 |     fn prod(&self,range:impl std::ops::RangeBounds<usize>)->M::S{
    |        ^^^^
...
182 |     fn max_right(&self,mut l:usize,mut f:impl FnMut(M::S)->bool)->usize{
    |        ^^^^^^^^^
...
214 |     fn min_left(&self,mut r:usize,mut f:impl FnMut(M::S)->bool)->usize{
    |        ^^^^^^^^

warning: type alias `ModInt1000000007` is never used
   --> src/main.rs:273:6
    |
273 | type ModInt1000000007=ModInt<1000000007>;
    |      ^^^^^^^^^^^^^^^^

warning: methods `val` and `pow` are never used
   --> src/main.rs:456:8
    |
450 | trait ModIntBase:Default+std::str::FromStr+Copy+Eq+std::hash::Hash+std::fmt::Display+std::fmt::Debug
    |       ---------- methods in this trait
...
456 |     fn val(self)->u32;
    |        ^^^
...
459 |     fn pow(self,k:u64)->Self;
    |        ^^^

warning: methods `inv`, `perm`, and `multi_choose` are never used
   --> src/main.rs:498:8
    |
472 | impl<M:ModIntBase> Pre<M>{
    | ------------------------- methods in this implementation
...
498 |     fn inv(&self,n:usize)->M{
    |        ^^^
...
503 |     fn perm(&self,n:usize,k:usize)->M{
    |        ^^^^
...
517 |     fn multi_cho

ソースコード

diff #

#![allow(non_snake_case)]



fn main(){
    proconio::input!{
        n:usize,
        a:[usize;n],
    }

    // naive(n,&a);

    use std::collections::*;
    let mut set=(0..n).map(|i|(i,a[i])).collect::<BTreeSet<_>>();
    let mut perm=vec![!0;n];
    
    let mut que=(0..n).filter(|&i|a[i]==0).collect::<Vec<_>>();
    let mut it=0..;
    while let Some(i)=que.pop(){
        let &(ci,val)=set.range((i,0)..).next().unwrap();
        assert!(i==ci);
        perm[i]=it.next().unwrap();

        set.remove(&(i,val));
        macro_rules! update{
            ($ni:expr,$val:expr)=>{
                set.remove(&($ni,$val));
                if $val==0{
                    println!("0");
                    return;
                }
                set.insert(($ni,$val-1));
                if $val==1{
                    que.push($ni);
                }
            }
        }
        if let Some(&(ni,val))=set.range((i,0)..).next(){
            update!(ni,val);
        }
        if let Some(&(ni,val))=set.range(..(i,0)).rev().next(){
            update!(ni,val);
        }
    }

    if !set.is_empty(){
        println!("0");
        return;
    }

    // impl_monoid!(Max,(usize,usize),(0,0),|a:(usize,usize),b:(usize,usize)|a.max(b));
    // let seg=Segtree::<Max>::from((0..n).map(|i|(perm[i],i)).collect::<Vec<_>>());

    type M=ModInt998244353;
    let pre=Pre::<M>::new(n);

    fn rec(perm:&[usize],l:usize,r:usize,pre:&Pre<M>)->M{
        if l==r{
            M::new(1)
        } else{
            let mi=(l..r).min_by_key(|&i|perm[i]).unwrap();
            pre.choose(r-l-1,mi-l)*rec(perm,l,mi,pre)*rec(perm,mi+1,r,pre)
        }
    }

    let ans=rec(&perm,0,n,&pre);
    println!("{ans}");
}



// fn naive(n:usize,a:&[usize]){
//     use itertools::*;
//     let mut ans=0;
    
//     for is in (0..n).permutations(n){
//         let mut b=vec![!0;n];
//         for &i in &is{
//             b[i]=0;
//             if let Some(ni)=(0..i).rev().find(|&ni|b[ni]!=!0){
//                 b[ni]+=1;
//             }
//             if let Some(ni)=(i+1..n).find(|&ni|b[ni]!=!0){
//                 b[ni]+=1;
//             }
//         }

//         if a==b{
//             ans+=(a==&b) as usize;
//         }
//     }

//     eprintln!("#{ans}");
// }



#[derive(Clone)]
struct Segtree<M:Monoid>{
    n:usize,
    size:usize,
    a:Vec<M::S>,
}
impl<M:Monoid> From<Vec<M::S>> for Segtree<M>{
    fn from(v:Vec<M::S>)->Self{
        let n=v.len();
        let size=n.next_power_of_two();
        let mut a=vec![M::e();size*2];
        a[size..size+n].copy_from_slice(&v);

        for i in (1..size).rev(){
            a[i]=M::op(a[i*2],a[i*2+1]);
        }
        Segtree{n,size,a}
    }
}
impl<M:Monoid> Segtree<M>{
    fn new(n:usize)->Self{
        let size=n.next_power_of_two();
        Segtree{
            n,size,
            a:vec![M::e();size*2],
        }
    }

    fn set(&mut self,mut i:usize,v:M::S){
        assert!(i<self.n);
        i+=self.size;
        self.a[i]=v;
        i/=2;
        while i!=0{
            self.a[i]=M::op(self.a[i*2],self.a[i*2+1]);
            i/=2;
        }
    }

    fn get(&self,i:usize)->M::S{
        assert!(i<self.n);
        self.a[i+self.size]
    }

    fn prod(&self,range:impl std::ops::RangeBounds<usize>)->M::S{
        use std::ops::Bound::*;
        let mut u=match range.start_bound(){
            Included(&a)=>a,
            Excluded(&a)=>a+1,
            Unbounded=>0,
        };
        let mut v=match range.end_bound(){
            Included(&a)=>a+1,
            Excluded(&a)=>a,
            Unbounded=>self.n,
        };
        assert!(u<=v && v<=self.n);

        if (u,v)==(0,self.n){
            return self.a[1];
        }

        let mut um=M::e();
        let mut vm=M::e();
        u+=self.size;
        v+=self.size;

        while u<v{
            if u&1!=0{
                um=M::op(um,self.a[u]);
                u+=1;
            }
            if v&1!=0{
                v-=1;
                vm=M::op(self.a[v],vm);
            }
            u/=2;
            v/=2;
        }

        M::op(um,vm)
    }

    // l..rがtrueで、l..=rがfalse
    fn max_right(&self,mut l:usize,mut f:impl FnMut(M::S)->bool)->usize{
        assert!(l<=self.n && f(M::e()));
        if l==self.n{
            return self.n;
        }
        l+=self.size;
        let mut m=M::e();
        
        loop{
            l>>=l.trailing_zeros();

            if !f(M::op(m,self.a[l])){
                while l<self.size{
                    l*=2;
                    let res=M::op(m,self.a[l]);
                    if f(res){
                        m=res;
                        l+=1;
                    }
                }
                return l-self.size;
            }

            m=M::op(m,self.a[l]);
            l+=1;
            if l&l.wrapping_neg()==l{
                return self.n;
            }
        }
    }

    // l..rがtrueで、l-1..rがfalse
    fn min_left(&self,mut r:usize,mut f:impl FnMut(M::S)->bool)->usize{
        assert!(r<=self.n && f(M::e()));
        if r==0{
            return 0;
        }
        r+=self.size;
        let mut m=M::e();

        loop{
            r-=1;
            r>>=r.trailing_ones();
            r=r.max(1);

            if !f(M::op(self.a[r],m)){
                while r<self.size{
                    r=r*2+1;
                    let res=M::op(self.a[r],m);
                    if f(res){
                        m=res;
                        r-=1;
                    }
                }
                return r+1-self.size;
            }

            m=M::op(self.a[r],m);
            if r&r.wrapping_neg()==r{
                return 0;
            }
        }
    }
}


trait Monoid{
    type S:Copy;
    fn e()->Self::S;
    fn op(left:Self::S,right:Self::S)->Self::S;
}


#[macro_export]
macro_rules! impl_monoid{
    ($t:ident,$item:ty,$e:expr,$op:expr)=>{
        #[derive(Clone,Copy)]
        struct $t();
        impl Monoid for $t{
            type S=$item;
            fn e()->$item{ $e }
            fn op(left:$item,right:$item)->$item{
                $op(left,right)
            }
        }
    };
}



type ModInt998244353=ModInt<998244353>;
type ModInt1000000007=ModInt<1000000007>;



#[derive(Clone,Copy,PartialEq,Eq,Default,Hash)]
struct ModInt<const MOD:u32>(u32);
impl<const MOD:u32> ModIntBase for ModInt<MOD>{
    fn modulus()->u32{ MOD }
    fn val(self)->u32{ self.0 }
    fn new(v:impl RemU32)->Self{ Self(v.rem_u32(MOD)) }

    fn inv(self)->Self{
        assert!(self.0!=0);

        let (mut a,mut b)=(self.0 as i64,MOD as i64);
        let (mut u,mut v)=(1,0);
        while b!=0{
            let t=a/b;
            (a,b)=(b,a-t*b);
            (u,v)=(v,u-t*v);
        }
        assert!(a==1);

        if u<0{
            u+=MOD as i64;
        }
        Self(u as u32)
    }

    fn pow(self,mut k:u64)->Self{
        let mut pow2=self;
        let mut ret=Self(1);
        while k>0{
            if k&1==1{
                ret*=pow2;
            }
            pow2*=pow2;
            k>>=1;
        }
        ret
    }
}


impl<const MOD:u32> std::fmt::Display for ModInt<MOD>{
    fn fmt(&self,f:&mut std::fmt::Formatter)->std::fmt::Result{
        write!(f,"{}",self.0)
    }
}
impl<const MOD:u32> std::fmt::Debug for ModInt<MOD>{
    fn fmt(&self,f:&mut std::fmt::Formatter)->std::fmt::Result{
        write!(f,"{}",self.0)
    }
}


impl<const MOD:u32> std::ops::Add for ModInt<MOD>{
    type Output=Self;
    fn add(self,a:Self)->Self{
        let mut new=self.0+a.0;
        if MOD<=new{
            new-=MOD;
        }
        Self(new)
    }
}
impl<const MOD:u32> std::ops::Sub for ModInt<MOD>{
    type Output=Self;
    fn sub(self,a:Self)->Self{
        let mut new=self.0-a.0;
        if 0>new as i32{
            new+=MOD;
        }
        Self(new)
    }
}
impl<const MOD:u32> std::ops::Mul for ModInt<MOD>{
    type Output=Self;
    fn mul(self,a:Self)->Self{
        Self((self.0 as u64*a.0 as u64%MOD as u64) as u32)
    }
}
impl<const MOD:u32> std::ops::Div for ModInt<MOD>{
    type Output=Self;
    fn div(self,a:Self)->Self{
        self*a.inv()
    }
}
impl<const MOD:u32> std::ops::Neg for ModInt<MOD>{
    type Output=Self;
    fn neg(self)->Self{
        if self.0==0{
            return self;
        }
        Self(MOD-self.0)
    }
}


impl<const MOD:u32> std::str::FromStr for ModInt<MOD>{
    type Err=<u64 as std::str::FromStr>::Err;
    fn from_str(s:&str)->Result<Self,Self::Err>{
        let x=s.parse::<u64>()?;
        Ok(Self::new(x))
    }
}


macro_rules! impl_modint_ops{
    ($trait:ident,$func:ident,$assign_trait:ident,$assign_func:ident,$op:tt)=>{
        impl<const MOD:u32> std::ops::$assign_trait for ModInt<MOD>{
            fn $assign_func(&mut self,a:Self){
                *self=*self $op a
            }
        }
        impl<T:RemU32,const MOD:u32> std::ops::$trait<T> for ModInt<MOD>{
            type Output=Self;
            fn $func(self,a:T)->Self{
                self $op Self::new(a)
            }
        }
        impl<T:RemU32,const MOD:u32> std::ops::$assign_trait<T> for ModInt<MOD>{
            fn $assign_func(&mut self,a:T){
                *self=*self $op Self::new(a)
            }
        }
    }
}
impl_modint_ops!(Add,add,AddAssign,add_assign,+);
impl_modint_ops!(Sub,sub,SubAssign,sub_assign,-);
impl_modint_ops!(Mul,mul,MulAssign,mul_assign,*);
impl_modint_ops!(Div,div,DivAssign,div_assign,/);


impl<const MOD:u32> std::iter::Sum for ModInt<MOD>{
    fn sum<I:Iterator<Item=Self>>(iter:I)->Self{
        iter.fold(Self(0),|sum,x|sum+x)
    }
}
impl<const MOD:u32> std::iter::Product for ModInt<MOD>{
    fn product<I:Iterator<Item=Self>>(iter:I)->Self{
        iter.fold(Self(1),|prod,x|prod*x)
    }
}


trait RemU32{
    fn rem_u32(self,m:u32)->u32;
}
macro_rules! impl_rem_u32{
    ($($ty:tt),*)=>{
        $(
            impl RemU32 for $ty{
                fn rem_u32(self,m:u32)->u32{
                    (self as i64).rem_euclid(m as i64) as _
                }
            }
        )*
    }
}
impl_rem_u32!(i32,i64);


macro_rules! impl_rem_u32{
    ($($ty:tt),*)=>{
        $(
            impl RemU32 for $ty{
                fn rem_u32(self,m:u32)->u32{
                    (self%(m as $ty)) as _
                }
            }
        )*
    }
}
impl_rem_u32!(u32,u64,usize);


trait ModIntBase:Default+std::str::FromStr+Copy+Eq+std::hash::Hash+std::fmt::Display+std::fmt::Debug
    +std::ops::Neg<Output=Self>+std::ops::Add<Output=Self>+std::ops::Sub<Output=Self>
    +std::ops::Mul<Output=Self>+std::ops::Div<Output=Self>
    +std::ops::AddAssign+std::ops::SubAssign+std::ops::MulAssign+std::ops::DivAssign
{
    fn modulus()->u32;
    fn val(self)->u32;
    fn new(v:impl RemU32)->Self;
    fn inv(self)->Self;
    fn pow(self,k:u64)->Self;
}



// Modを超える数はpanicする
// 注意:
//      Modは素数
//      multi_choose(n,k)を使うときは,fac(n+k-1)まで必要になる
struct Pre<M:ModIntBase>{
    fac:Vec<M>,
    finv:Vec<M>,
}
impl<M:ModIntBase> Pre<M>{
    fn new(n:usize)->Self{
        assert!(n<M::modulus() as usize);

        let mut fac=vec![M::new(1);n+1];
        for i in 1..=n{
            fac[i]=fac[i-1]*M::new(i);
        }

        let mut finv=vec![M::new(0);n+1];
        finv[n]=fac[n].inv();
        for i in (1..=n).rev(){
            finv[i-1]=finv[i]*M::new(i);
        }
        
        Self{fac,finv}
    }

    fn fac(&self,n:usize)->M{
        self.fac[n]
    }

    fn finv(&self,n:usize)->M{
        self.finv[n]
    }

    fn inv(&self,n:usize)->M{
        assert!(n!=0);
        self.finv[n]*self.fac[n-1]
    }

    fn perm(&self,n:usize,k:usize)->M{
        if n<k || (n as i64)<0 || (k as i64)<0{
            return M::new(0);
        }
        self.fac(n)*self.finv(n-k)
    }

    fn choose(&self,n:usize,k:usize)->M{
        if n<k || (n as i64)<0 || (k as i64)<0{
            return M::new(0);
        }
        self.fac(n)*self.finv(k)*self.finv(n-k)
    }

    fn multi_choose(&self,n:usize,k:usize)->M{
        if (n as i64)<0 || (k as i64)<0{
            return M::new(0);
        }
        if n==0 && k==0{
            return M::new(1);
        }
        self.choose(n+k-1,k)
    }
}
0