AtCoder Beginner Contest 344 (ABC344) 復習の提出

ABC344を解き直しました。
コンテスト時はA~Eの5完でした。F解きたかった…

復習したときのメモを動画にして提出したもののみ載せます。

自作ライブラリを使用し、ローカルで事前に明らかに未使用な部分を除いて展開する形で提出しています。展開前のソースコードを記述します。
AtCoderで使えるクレートに含まれない関数などを使っている可能性があること、破壊的変更をこの記事の投稿後にしている可能性があることにご注意ください。
github.com

A問題

atcoder.jp
atcoder.jp

use itertools::Itertools;
#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(s:String);
    let ss=s.split('|').collect_vec();
    outputcatln!(ss[0],ss[2]);
}

B問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use proconio::is_stdin_empty;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    let mut avec=vec![];
    while !is_stdin_empty() {
        input!(a:usize);
        avec.push(a);
    }
    avec.reverse();
    avec.outputlns();
}

C問題

atcoder.jp
atcoder.jp

use std::collections::BTreeSet;

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,a:[usize;n],m:usize,b:[usize;m],l:usize,c:[usize;l],q:usize,x:[usize;q]);
    let mut s=BTreeSet::new();
    for &a in &a {
        for &b in &b {
            for &c in &c {
                s.insert(a+b+c);
            }
        }
    }
    for x in &x {
        output_yes_or_no(s.contains(x));
    }
}

atcoder.jp

use bitset_fixed::BitSet;
#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,a:[usize;n],m:usize,b:[usize;m],l:usize,c:[usize;l],q:usize,x:[usize;q]);
    let mut s=BitSet::new(3*E[8]+1);
    for &a in &a {
        for &b in &b {
            for &c in &c {
                s.set(a+b+c, true);
            }
        }
    }
    for &x in &x {
        output_yes_or_no(s[x]);
    }
}

D問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use proconio::marker::Chars;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(t:Chars,n:usize);
    let l=t.len();
    let mut a=vec![0;n];
    let mut s=vec![vec![vec![]];n];
    for i in 0..n {
        input!(ai:usize,si:[Chars;ai]);
        a[i]=ai;
        s[i]=si;
    }
    let mut dp=vec![vec![E[18];l+1];n+1];
    dp[0][0]=0;
    for i in 0..n {
        dp[i+1]=dp[i].clone();
        for j in 0..s[i].len() {
            for k in 0..l {
                let jl=s[i][j].len();
                if k+jl>l {
                    break;
                }
                if t[k..k+jl]==s[i][j] {
                    let tmp=dp[i][k]+1;
                    dp[i+1][k+jl].chmin(tmp);
                }
            }
        }
    }
    dp[n][l].output_val_or(E[18]);
}

E問題

atcoder.jp
atcoder.jp

use std::collections::BTreeMap;

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,a:[usize;n],q:usize);
    let list=DoublyLinkedList::new();
    let mut set=BTreeMap::new();
    let mut cur=list.begin_sentinel();
    for &a in &a {
        cur=cur.clone().borrow_mut().insert_next(a).unwrap();
        set.insert(a, cur.clone());
    }
    for _ in 0..q {
        input!(q:usize);
        if q==1 {
            input!(x:usize,y:usize);
            let xnode=set[&x].clone();
            let ynode=xnode.borrow_mut().insert_next(y).unwrap();
            set.insert(y, ynode);
        } else {
            input!(x:usize);
            let xnode=set[&x].clone();
            xnode.borrow_mut().remove();
            set.remove(&x);
        }
    }
    let mut ans=vec![];
    for node in &list {
        ans.push(node.borrow().get().unwrap());
    }
    ans.outputln();
}

F問題

atcoder.jp
atcoder.jp

use std::{cmp::Reverse, collections::BTreeMap};

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use num::Integer;

#[allow(unstable_name_collisions)]

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,p:[[usize;n];n],r:[[usize;n-1];n],d:[[usize;n];n-1]);
    let mut dp=vec![vec![BTreeMap::<usize,(usize,Reverse<usize>)>::new();n];n];
    dp[0][0].insert(p[0][0], (0,Reverse(0)));
    for i in 0..n {
        for j in 0..n {
            if j+1<n {
                let (left,right)=dp[i].split_at_mut(j+1);
                for (&pmax,&(cnt,Reverse(m))) in &left[j] {
                    let pcnt=if m>=r[i][j] {
                        0
                    } else {
                        (r[i][j]-m).div_ceil(&pmax)
                    };
                    let new_pmax=max(pmax, p[i][j+1]);
                    let tmp=(cnt+1+pcnt,Reverse(m+pcnt*pmax-r[i][j]));
                    if !right[0].contains_key(&new_pmax) || right[0][&new_pmax]>tmp {
                        right[0].insert(new_pmax, tmp);
                    }
                }
            }
            if i+1<n {
                let (left,right)=dp.split_at_mut(i+1);
                for (&pmax,&(cnt,Reverse(m))) in &left[i][j] {
                    let pcnt=if m>=d[i][j] {
                        0
                    } else {
                        (d[i][j]-m).div_ceil(&pmax)
                    };
                    let new_pmax=max(pmax, p[i+1][j]);
                    let tmp=(cnt+1+pcnt,Reverse(m+pcnt*pmax-d[i][j]));
                    if !right[0][j].contains_key(&new_pmax) || right[0][j][&new_pmax]>tmp {
                        right[0][j].insert(new_pmax, tmp);
                    }
                }
            }
        }
    }
    let mut ans=(usize::MAX,Reverse(0));
    for (_,&tmp) in &dp[n-1][n-1] {
        ans.chmin(tmp);
    }
    outputln!(ans.0);
}

atcoder.jp

use std::cmp::Reverse;

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use num::Integer;

#[allow(unstable_name_collisions)]

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,p:[[usize;n];n],r:[[usize;n-1];n],d:[[usize;n];n-1]);
    let mut dist=vec![vec![vec![vec![usize::MAX;n];n];n];n];
    for i in 0..n {
        for j in 0..n {
            for k in i..n {
                for l in j..n {
                    if (i,j)==(k,l) {
                        dist[i][j][k][l]=0;
                    }
                    if l+1<n {
                        let tmp=dist[i][j][k][l]+r[k][l];
                        dist[i][j][k][l+1].chmin(tmp);
                    }
                    if k+1<n {
                        let tmp=dist[i][j][k][l]+d[k][l];
                        dist[i][j][k+1][l].chmin(tmp);
                    }
                }
            }
        }
    }
    let mut dp=vec![vec![(usize::MAX,Reverse(0));n];n];
    dp[0][0]=(0,Reverse(0));
    for i in 0..n {
        for j in 0..n {
            for k in i..n {
                for l in j..n {
                    if (i,j)==(k,l) {
                        continue;
                    }
                    if (k,l)!=(n-1,n-1) && p[i][j]>=p[k][l] {
                        continue;
                    }
                    let (cnt,Reverse(m))=dp[i][j];
                    if cnt==usize::MAX {
                        continue;
                    }
                    let pcnt=if m>=dist[i][j][k][l] {
                        0
                    } else {
                        (dist[i][j][k][l]-m).div_ceil(&p[i][j])
                    };
                    let tmp=(cnt+k-i+l-j+pcnt,Reverse(m+pcnt*p[i][j]-dist[i][j][k][l]));
                    dp[k][l].chmin(tmp);
                }
            }
        }
    }
    outputln!(dp[n-1][n-1].0);
}

G問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use num::Integer;

#[allow(unstable_name_collisions)]

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,mut xy:[(isize,isize);n],q:usize,g0:isize,ra:isize,rb:isize);
    xy.sort();
    let mut pq=RevBinaryHeap::<(isize,usize)>::new();
    for i in 0..n-1 {
        if xy[i].0!=xy[i+1].0 {
            pq.push(((xy[i+1].1-xy[i].1).div_ceil(&(xy[i+1].0-xy[i].0)),i));
        }
    }
    let mut ab=vec![(0,0);q];
    let mut g=g0;
    for i in 0..q {
        ab[i]=(-ra+gen(&mut g)%(2*ra+1),-rb+(gen(&mut g)*((1<<31)-1)+gen(&mut g))%(2*rb+1));
    }
    ab.sort();
    let mut ans=0;
    for &(a,b) in &ab {
        while let Some(&(bound,i))=pq.peek() {
            if bound>a {
                break;
            }
            pq.pop();
            if xy[i].0>=xy[i+1].0 || (xy[i+1].1-xy[i].1).div_ceil(&(xy[i+1].0-xy[i].0))!=bound {
                continue;
            }
            xy.swap(i, i+1);
            if i>0 && xy[i-1].0<xy[i].0 {
                pq.push(((xy[i].1-xy[i-1].1).div_ceil(&(xy[i].0-xy[i-1].0)),i-1));
            }
            if i+2<n && xy[i+1].0<xy[i+2].0 {
                pq.push(((xy[i+2].1-xy[i+1].1).div_ceil(&(xy[i+2].0-xy[i+1].0)),i+1));
            }
        }
        ans+=n-usize_binary_search(n, false, |mid| {
            xy[mid].1>=a*xy[mid].0+b
        });
    }
    outputln!(ans);
}

fn gen(g: &mut isize) -> isize {
    *g*=48271;
    *g%=(1<<31)-1;
    *g
}

AtCoder Beginner Contest 343 (ABC343) 復習の提出

ABC343を解き直しました。
コンテスト時はA~Fの6完でした。ひさしぶりに温まったので良かったですが、こういうセットは全完できるようになりたいですね…

復習したときのメモを動画にして提出したもののみ載せます。

自作ライブラリを使用し、ローカルで事前に明らかに未使用な部分を除いて展開する形で提出しています。展開前のソースコードを記述します。
AtCoderで使えるクレートに含まれない関数などを使っている可能性があること、破壊的変更をこの記事の投稿後にしている可能性があることにご注意ください。
github.com

A問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(a:usize,b:usize);
    outputif(a+b>0, 0, 1);
}

B問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,a:[[usize;n];n]);
    for i in 0..n {
        for j in 0..n {
            if a[i][j]==1 {
                print!("{} ", j+1);
            }
        }
        println!();
    }
}

C問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use num_integer::Roots;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize);
    for x in (1..=n.cbrt()).rev() {
        let k=x*x*x;
        let k=format!("{}",k);
        let krev=k.chars().rev().collect::<String>();
        if k==krev {
            outputln!(k);
            return;
        }
    }
}

D問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use proconio::marker::Usize1;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,t:usize,ab:[(Usize1,usize);t]);
    let mut p=vec![0;n];
    let mut ms=MultiSet::new();
    ms.insert(0, n);
    for &(a,b) in &ab {
        ms.remove_one(p[a]);
        p[a]+=b;
        ms.insert_one(p[a]);
        outputln!(ms.len());
    }
}

E問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(v1:usize,v2:usize,v3:usize);
    let (a1,b1,c1)=(0,0,0);
    for a2 in -7..=7 {
        for b2 in -7..=7 {
            for c2 in -7..=7 {
                for a3 in -7..=7 {
                    for b3 in -7..=7 {
                        for c3 in -7..=7 {
                            let v_3=max(min!(a1,a2,a3)+7-max!(a1,a2,a3), 0) as usize*max(min!(b1,b2,b3)+7-max!(b1,b2,b3), 0) as usize*max(min!(c1,c2,c3)+7-max!(c1,c2,c3), 0) as usize;
                            let v_2=max(min(a1,a2)+7-max(a1,a2), 0) as usize*max(min(b1,b2)+7-max(b1,b2), 0) as usize*max(min(c1,c2)+7-max(c1,c2), 0) as usize
                            +max(min(a2,a3)+7-max(a2,a3), 0) as usize*max(min(b2,b3)+7-max(b2,b3), 0) as usize*max(min(c2,c3)+7-max(c2,c3), 0) as usize
                            +max(min(a3,a1)+7-max(a3,a1), 0) as usize*max(min(b3,b1)+7-max(b3,b1), 0) as usize*max(min(c3,c1)+7-max(c3,c1), 0) as usize
                            -3*v_3;
                            let v_1=3*7*7*7-2*v_2-3*v_3;
                            if (v1,v2,v3)==(v_1,v_2,v_3) {
                                outputln!("Yes");
                                outputln!(a1,b1,c1,a2,b2,c2,a3,b3,c3);
                                return;
                            }
                        }
                    }
                }
            }
        }
    }
    outputln!("No");
}

F問題

atcoder.jp
atcoder.jp

use ac_library::{Monoid, Segtree};
#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use proconio::marker::Usize1;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,q:usize,a:[usize;n]);
    let mut st=Segtree::<M>::new(n);
    for i in 0..n {
        st.set(i, ((a[i],1),(0,0)));
    }
    for _ in 0..q {
        input!(q:usize);
        if q==1 {
            input!(p:Usize1,x:usize);
            st.set(p, ((x,1),(0,0)));
        } else {
            input!(l:Usize1,r:usize);
            outputln!(st.prod(l..r).1.1);
        }
    }
}

struct M;

impl Monoid for M {
    type S = ((usize,usize),(usize,usize));
    fn identity() -> Self::S {
        ((1,0),(0,0))
    }
    fn binary_operation(a: &Self::S, b: &Self::S) -> Self::S {
        let mut ms=MultiSet::new();
        ms.insert(0, 0);
        ms.increase(a.0.0, a.0.1);
        ms.increase(a.1.0, a.1.1);
        ms.increase(b.0.0, b.0.1);
        ms.increase(b.1.0, b.1.1);
        let mut iter=ms.iter().rev();
        let c1=iter.next().unwrap();
        let c2=iter.next().unwrap();
        ((*c1.0,*c1.1),(*c2.0,*c2.1))
    }
}

G問題

atcoder.jp
atcoder.jp

use ac_library::z_algorithm;
#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,mut s:[String;n]);
    s.sort_and_dedup();
    let (n,s)=(s.len(),s);
    let mut ss=s.clone();
    for i in 0..n {
        for j in 0..n {
            if i==j {
                continue;
            }
            ss[i].push('$');
            ss[i].push_str(&s[j]);
        }
    }
    let zs=vec_range(0, n, |i| z_algorithm(&ss[i]));
    let mut is_necessary=vec![true;n];
    let mut l=vec![vec![0;n];n];
    for i in 0..n {
        for idx in s[i].len()+1..zs[i].len() {
            if zs[i][idx]==s[i].len() {
                is_necessary[i]=false;
                break;
            }
        }
        if !is_necessary[i] {
            continue;
        }
        let mut cur=s[i].len()+1;
        for j in 0..n {
            if i==j {
                continue;
            }
            for idx in cur..cur+s[j].len() {
                if idx+zs[i][idx]==cur+s[j].len() {
                    l[j][i]=zs[i][idx];
                    break;
                }
            }
            cur+=s[j].len()+1;
        }
    }
    let mut dp=vec![vec![0;n];1<<n];
    for s in 1usize..1<<n {
        for v in 0..n {
            if s&(1<<v)==0 {
                continue;
            }
            for u in 0..n {
                if s&(1<<u)>0 {
                    continue;
                }
                let tmp=dp[s][v]+l[v][u];
                dp[s+(1<<u)][u].chmax(tmp);
            }
        }
    }
    let mut ans=0;
    let mut bits=0;
    for v in 0..n {
        if is_necessary[v] {
            ans+=s[v].len();
            bits+=1<<v;
        }
    }
    let mut intersections=0;
    for v in 0..n {
        intersections.chmax(dp[bits][v]);
    }
    ans-=intersections;
    outputln!(ans);
}

AtCoder Beginner Contest 342 (ABC342) 復習の提出

ABC342を解き直しました。
コンテスト時はA~Dの4完でした。Fが合ってたのに合っていないと思い込んで提出しなかったのが痛恨すぎる…(レート+300のパフォだったはずがレート-300のパフォになりました…)

復習したときのメモを動画にして提出したもののみ載せます。

自作ライブラリを使用し、ローカルで事前に明らかに未使用な部分を除いて展開する形で提出しています。展開前のソースコードを記述します。
AtCoderで使えるクレートに含まれない関数などを使っている可能性があること、破壊的変更をこの記事の投稿後にしている可能性があることにご注意ください。
github.com

A問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use proconio::marker::Chars;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(s:Chars);
    let majority=if s[0]==s[1] {
        s[0]
    } else {
        s[2]
    };
    for i in 0..s.len() {
        if s[i]!=majority {
            outputln!(i+1);
        }
    }
}

B問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use proconio::marker::Usize1;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,p:[Usize1;n],q:usize,ab:[(Usize1,Usize1);q]);
    let mut pinv=vec![0;n];
    for i in 0..n {
        pinv[p[i]]=i;
    }
    for i in 0..q {
        if pinv[ab[i].0]<pinv[ab[i].1] {
            outputln!(ab[i].0+1);
        } else {
            outputln!(ab[i].1+1);
        }
    }
}

C問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use proconio::marker::Chars;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,s:Chars,q:usize,cd:[(char,char);q]);
    let mut results=['a';26];
    for i in 0..26 {
        results[i]=i.to_lowercase();
        for &(c,d) in &cd {
            if results[i]==c {
                results[i]=d;
            }
        }
    }
    for i in 0..n {
        print!("{}",results[s[i].from_lowercase()]);
    }
    println!();
}

D問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,a:[usize;n]);
    let mut zeros=0usize;
    let mut cnts=vec![0usize;2*E[5]+1];
    for &a in &a {
        if a==0 {
            zeros+=1;
            continue;
        }
        let mut aa=a;
        while aa%4==0 {
            aa/=4;
        }
        let mut m=3;
        while m*m<=a {
            while aa%(m*m)==0 {
                aa/=m*m;
            }
            m+=2;
        }
        cnts[aa]+=1;
    }
    let mut ans=0usize;
    for cnt in cnts {
        ans+=(cnt)*(cnt.saturating_sub(1))/2;
    }
    ans+=(zeros)*(zeros.saturating_sub(1))/2;
    ans+=zeros*(n-zeros);
    outputln!(ans);
}

E問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use proconio::marker::Usize1;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,m:usize,ldkcab:[(usize,usize,usize,usize,Usize1,Usize1);m]);
    let mut g=vec![vec![];n];
    for &(l,d,k,c,a,b) in &ldkcab {
        g[b].push((a,c,l,d,k));
    }
    let inf=E[19];
    let mut dist=vec![usize::MAX;n];
    dist[n-1]=0;
    let mut pq=RevBinaryHeap::<(usize,usize)>::new();
    pq.push((dist[n-1],n-1));
    while let Some((d,v))=pq.pop() {
        if dist[v]<d {
            continue;
        }
        for &(u,c,l,d,k) in &g[v] {
            if inf-dist[v]<l+c {
                continue;
            }
            let w=if (inf-dist[v]-c-l)/d<k {
                c+inf-dist[v]-(l+(inf-dist[v]-c-l)/d*d+c)
            } else {
                c+inf-dist[v]-(l+(k-1)*d+c)
            };
            if dist[v].saturating_add(w)<dist[u] {
                dist[u]=dist[v].saturating_add(w);
                pq.push((dist[u],u));
            }
        }
    }
    for v in 0..n-1 {
        outputif(dist[v]<usize::MAX, inf.saturating_sub(dist[v]), "Unreachable");
    }
}

F問題

atcoder.jp
atcoder.jp

use ac_library::Segtree;
#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,l:usize,d:usize);
    let mut dp_y=Segtree::<Add<f64>>::new(2*n+1);
    dp_y.set(0, 1.);
    for i in 1..l {
        dp_y.set(i, dp_y.prod(i.saturating_sub(d)..i)/d as f64);
    }
    for i in l..l+d {
        dp_y.set(i, dp_y.prod(i.saturating_sub(d)..l)/d as f64);
    }
    let mut dp=Segtree::<Add<f64>>::new(2*n+1);
    let mut ans=0.;
    for i in (0..=n).rev() {
        dp.set(i, max(1.-dp_y.prod(max(i,l)..=n),dp.prod(i+1..=i+d)/d as f64));
        ans.chmax(dp.get(i));
    }
    outputln!(dp.get(0));
}

G問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use proconio::marker::Usize1;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,a:[usize;n],q:usize);
    let mut t=RangeBinaryHeap::<MultiSet<usize>>::new(n);
    for i in 0..n {
        t.get_mut(i).insert_one(a[i]);
    }
    let mut queries=vec![(0,0,0);q];
    for i in 0..q {
        input!(q:usize);
        if q==1 {
            input!(l:Usize1,r:usize,x:usize);
            queries[i]=(l,r,x);
            for (idx,_) in t.ranges(l..r) {
                t[idx].insert_one(x);
            }
        } else if q==2 {
            input!(i:Usize1);
            let (l,r,x)=queries[i];
            for (idx,_) in t.ranges(l..r) {
                t[idx].remove_one(x);
            }
        } else {
            input!(i:Usize1);
            let mut ans=0;
            for i in t.indices(i) {
                if let Some((&val,_))=t[i].last_key_value() {
                    ans.chmax(val);
                }
            }
            outputln!(ans);
        }
    }
}

AtCoder Regular Contest 172 (ARC172) (AからCまで、およびE) 復習の提出

ARC172を解き直しました。
コンテスト時はAの1完でした。Bの考察ミスに60分気付かなかったのが痛すぎますし、Cに行かずにEを詰め切れなかったのも悔しいです。

復習したときのメモを動画にして提出したもののみ載せます。

自作ライブラリを使用し、ローカルで事前に明らかに未使用な部分を除いて展開する形で提出しています。展開前のソースコードを記述します。
AtCoderで使えるクレートに含まれない関数などを使っている可能性があること、破壊的変更をこの記事の投稿後にしている可能性があることにご注意ください。
github.com

A問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(h:usize,w:usize,n:usize,mut a:[usize;n]);
    let mut sets=MultiSet::<(usize,usize)>::new();
    sets.insert_one((h,w));
    a.sort();
    a.reverse();
    for a in a {
        let l=1<<a;
        let mut hw=None;
        for (&(h,w),_) in &sets {
            if l<=h && l<=w {
                hw=Some((h,w));
                break;
            }
        }
        if let Some((h,w))=hw {
            sets.remove_one((h,w));
            if h>l {
                sets.insert_one((h-l,l));
            }
            if w>l {
                sets.insert_one((h,w-l));
            }
        } else {
            outputln!("No");
            return;
        }
    }
    outputln!("Yes");
}

B問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,k:usize,l:usize);
    let mut ans=Mint::new(1);
    let mut cur=l;
    for _ in 0..n {
        ans*=cur;
        if cur>0 && cur+n-k>l {
            cur-=1;
        }
    }
    outputln!(ans);
}

C問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use proconio::marker::Chars;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,c:Chars);
    let mut sum=vec![0;n];
    for i in 1..n {
        sum[i]=sum[i-1]+(c[i]=='A') as usize;
    }
    let mut ans=1;
    for i in 0..n-1 {
        if (sum[i]+(c[0]=='A') as usize).cmp(&(i-sum[i]+(c[0]=='B') as usize))!=(sum[i+1]).cmp(&(i+1-sum[i+1])) {
            ans+=1;
        }
    }
    outputln!(ans);
}

E問題

atcoder.jp
atcoder.jp

use ac_library::ModInt;
#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(q:usize);
    for _ in 0..q {
        input!(x:u32);
        let mut n=0;
        ModInt::set_modulus(E[2] as u32);
        for i in 1..E[2] {
            if ModInt::new(i).pow(i as u64)==ModInt::new(x) {
                n=i;
                break;
            }
        }
        if n==0 {
            outputln!(-1);
            continue;
        }
        let mut exists=true;
        for p in 3..=9 {
            let mut ok=false;
            ModInt::set_modulus(E[p] as u32);
            for k in 0..10 {
                let i=k*E[p-1]+n;
                if ModInt::new(i).pow(i as u64)==ModInt::new(x) {
                    n=i;
                    ok=true;
                    break;
                }
            }
            if !ok {
                outputln!(-1);
                exists=false;
                break;
            }
        }
        if exists {
            outputln!(n);
        }
    }
}

AtCoder Beginner Contest 341 (ABC341) 復習の提出

ABC341を解き直しました。
コンテスト時はA~Eの5完でした。苦しかったです。

復習したときのメモを動画にして提出したもののみ載せます。

自作ライブラリを使用し、ローカルで事前に明らかに未使用な部分を除いて展開する形で提出しています。展開前のソースコードを記述します。
AtCoderで使えるクレートに含まれない関数などを使っている可能性があること、破壊的変更をこの記事の投稿後にしている可能性があることにご注意ください。
github.com

A問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize);
    for _ in 0..n {
        print!("10");
    }
    println!("1");
}

B問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,mut a:[usize;n],st:[(usize,usize);n-1]);
    for i in 0..n-1 {
        a[i+1]=a[i+1]+a[i]/st[i].0*st[i].1;
    }
    outputln!(a[n-1]);
}

C問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use proconio::marker::Chars;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(h:usize,w:usize,_:usize,t:Chars,s:[Chars;h]);
    let mut ans=0;
    for i in 1..h-1 {
        for j in 1..w-1 {
            if s[i][j]=='#' {
                continue;
            }
            let mut cur_i=i;
            let mut cur_j=j;
            let mut ok=true;
            for &c in t.iter().rev() {
                macro_rules! matches {
                    ($cond:expr,$next_i:expr,$next_j:expr) => {
                        if $cond && s[$next_i][$next_j]=='.' {
                            cur_i=$next_i;
                            cur_j=$next_j;
                        } else {
                            ok=false;
                            break;
                        }
                    };
                }
                match c {
                    'L' => matches!(cur_j<w-1,cur_i,cur_j+1),
                    'R' => matches!(cur_j>0,cur_i,cur_j-1),
                    'U' => matches!(cur_i<h-1,cur_i+1,cur_j),
                    'D' => matches!(cur_i>0,cur_i-1,cur_j),
                    _ => ()
                };
            }
            if ok {
                ans+=1;
            }
        }
    }
    outputln!(ans);
}

D問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use num_integer::lcm;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,m:usize,k:usize);
    outputln!(binary_search(E[18], 0, |mid| {
        mid/n+mid/m-mid/lcm(n, m)*2>=k
    }));
}

E問題

atcoder.jp
atcoder.jp

use ac_library::LazySegtree;
#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use proconio::marker::{Chars, Usize1};

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,q:usize,s:Chars);
    let mut lst=LazySegtree::<RangeAffineRangeSum<Add<isize>>>::new(n);
    for i in 0..n {
        if (s[i]=='1') ^ (i%2>0) {
            lst.set(i, (1,1));
        } else {
            lst.set(i, (0,1));
        }
    }
    for _ in 0..q {
        input!(q:usize,l:Usize1,r:usize);
        if q==1 {
            lst.apply_range(l..r, (-1,1));
        } else {
            let prod=lst.prod(l..r);
            output_yes_or_no(prod.0==0 || prod.0==prod.1 as isize);
        }
    }
}

F問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use proconio::marker::Usize1;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,m:usize,uv:[(Usize1,Usize1);m],w:[usize;n],a:[usize;n]);
    let g=VecGraph::construct_graph(n, m, &uv);
    let mut dp=vec![0;n];
    let mut ws=vec_range(0, n, |i| (w[i],i));
    ws.sort();
    for (weight,idx) in ws {
        let list=&g.get()[idx];
        let l=list.len();
        let mut knapsack=vec![vec![0;weight];l+1];
        for i in 0..l {
            for j in 0..weight {
                let tmp=knapsack[i][j];
                knapsack[i+1][j].chmax(tmp);
                if j>=w[list[i].0] {
                    let tmp=knapsack[i][j-w[list[i].0]]+dp[list[i].0];
                    knapsack[i+1][j].chmax(tmp);
                }
            }
        }
        dp[idx]=1+knapsack[l].iter().max().unwrap();
    }
    let mut ans=0;
    for i in 0..n {
        ans+=dp[i]*a[i];
    }
    outputln!(ans);
}

G問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,a:[usize;n]);
    let mut stack=vec![(0.,0.)];
    let mut ans=vec![0.;n];
    let mut cnt=0.;
    let mut sum=0.;
    for i in (0..n).rev() {
        cnt+=1.;
        sum-=a[i] as f64;
        while stack.len()>1 && intersection(stack.get_from_last(2), &(cnt,sum))<intersection(stack.get_from_last(2), stack.get_from_last(1)) {
            stack.pop();
        }
        stack.push((cnt,sum));
        ans[i]=intersection(stack.get_from_last(2), stack.get_from_last(1));
    }
    for ans in ans {
        outputln!(ans);
    }
}

fn intersection(l1: &(f64,f64), l2: &(f64,f64)) -> f64 {
    (l2.1-l1.1)/(l1.0-l2.0)
}

AtCoder Beginner Contest 340 (ABC340) 復習の提出

ABC340を解き直しました。
コンテスト時はA~Fの6完でした。典型祭りでめちゃくちゃ温まりました。

復習したときのメモを動画にして提出したもののみ載せます。

自作ライブラリを使用し、ローカルで事前に明らかに未使用な部分を除いて展開する形で提出しています。展開前のソースコードを記述します。
AtCoderで使えるクレートに含まれない関数などを使っている可能性があること、破壊的変更をこの記事の投稿後にしている可能性があることにご注意ください。
github.com

A問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(a:usize,b:usize,d:usize);
    (a..=b).step_by(d).collect::<Vec<_>>().outputln();
}

B問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(q:usize);
    let mut vec=Vec::<usize>::new();
    for _ in 0..q {
        input!(q:usize);
        if q==1 {
            input!(x:usize);
            vec.push(x);
        } else {
            input!(k:usize);
            outputln!(vec.get_from_last(k));
        }
    }
}

C問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use memoise::memoise_map;

fn main() {
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
        };
    }

    input!(n:usize);
    outputln!(f(n));
}

#[memoise_map(n)]
fn f(n:usize) -> usize {
    if n==1 {
        0
    } else {
        f(n/2)+f((n+1)/2)+n
    }
}

D問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use proconio::marker::Usize1;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,abx:[(usize,usize,Usize1);n-1]);
    let mut vuw=Vec::new();
    for i in 0..n-1 {
        vuw.push((i,i+1,abx[i].0));
        vuw.push((i,abx[i].2,abx[i].1));
    }
    let g=VecGraph::construct_weighted_directed_graph(n, 2*n-2, &vuw);
    outputln!(g.dist_of_shortest_paths(0, true)[n-1]);
}

E問題

atcoder.jp
atcoder.jp

use ac_library::LazySegtree;
#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,m:usize,a:[usize;n],b:[usize;m]);
    let mut a=LazySegtree::<SegmentAffineTransform<DummyOperation<usize>>>::from(a);
    for i in 0..m {
        let cur_box=b[i];
        let mut balls=a.get(cur_box);
        a.set(cur_box, 0);
        let all=balls/n;
        a.apply_range(0..n, (1,all));
        balls-=all*n;
        if cur_box+balls<n {
            a.apply_range(cur_box+1..=cur_box+balls, (1,1));
        } else {
            a.apply_range(cur_box+1..n, (1,1));
            a.apply_range(0..=(cur_box+balls)%n, (1,1));
        }
    }
    (0..n).into_iter().map(|i| a.get(i)).collect::<Vec<_>>().outputln();
}

F問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(x:isize,y:isize);
    let mut a=0;
    let mut b=0;
    let g=extended_euclidean_algorithm(y, -x, &mut a, &mut b);
    if g.abs()==2 {
        outputln!(a,b);
    } else if g.abs()==1 {
        outputln!(2*a,2*b);
    } else {
        outputln!(-1);
    }
}

G問題

atcoder.jp
atcoder.jp

use std::collections::BTreeSet;

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use proconio::marker::Usize1;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,a:[Usize1;n],uv:[(Usize1,Usize1);n-1]);
    let mut g=VecGraph::construct_graph(n, n-1, &uv);
    let (_,par,depth,_,_,in_idx,out_idx)=g.easiest_hld_and_euler_tour();
    let lca=LCA::construct_lca_segtree(n, &par, &depth, &in_idx, &out_idx);
    let mut exists=BTreeSet::<usize>::new();
    let mut vertex_sets=vec![Vec::new();n];
    for i in 0..n {
        exists.insert(a[i]);
        vertex_sets[a[i]].push(i);
    }
    let mut ans=Mint::new(0);
    for &color in &exists {
        let (list,par)=g.auxiliary_tree(&mut vertex_sets[color], &in_idx, &out_idx, &lca);
        let len=list.len();
        let mut seen=vec![false;len];
        seen[0]=true;
        let mut dp=vec![(Mint::new(0),Mint::new(0));len];
        dfs(&mut ans, color, &a, 0, &vertex_sets[color], &list, &par, &mut seen, &mut dp);
    }
    outputln!(ans);
}

fn dfs(ans:&mut Mint,color:usize,a:&Vec<usize>,v:usize,vertex_set:&Vec<usize>,list:&Vec<Vec<usize>>,par:&Vec<usize>,seen:&mut Vec<bool>,dp:&mut Vec<(Mint,Mint)>) {
    for &u in &list[v] {
        if !seen[u] {
            seen[u]=true;
            dfs(ans, color, a, u, vertex_set, list, par, seen, dp);
            let tmp=dp[v].1*(dp[u].0+dp[u].1);
            dp[v].1=dp[v].1+dp[v].0*(dp[u].0+dp[u].1);
            dp[v].1=dp[v].1+tmp;
            dp[v].0=dp[v].0+(dp[u].0+dp[u].1);
        }
    }
    if a[vertex_set[v]]==color {
        dp[v].0+=1;
        *ans+=dp[v].0;
    }
    *ans+=dp[v].1;
}

AtCoder Regular Contest 171 (ARC171) (AからDまで) 復習の提出

ARC171を解き直しました。
コンテスト時はA~Bの2完でした。頑張って2完しましたが周りと比べると遅かったようです…

復習したときのメモを動画にして提出したもののみ載せます。

自作ライブラリを使用し、ローカルで事前に明らかに未使用な部分を除いて展開する形で提出しています。展開前のソースコードを記述します。
AtCoderで使えるクレートに含まれない関数などを使っている可能性があること、破壊的変更をこの記事の投稿後にしている可能性があることにご注意ください。
github.com

A問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(t:usize);
    for _ in 0..t {
        input!(n:usize,a:usize,b:usize);
        output_yes_or_no(a<=n && b<=min(n-a,(n+1)/2)*(n-a));
    }
}

B問題

atcoder.jp
atcoder.jp

use std::collections::BTreeSet;

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use proconio::marker::Usize1;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,a:[Usize1;n]);
    let mut ans=Mint::new(1);
    let mut cnt=0;
    let mut set=BTreeSet::<usize>::new();
    for i in 0..n {
        if a[i]<i {
            ans*=0;
            break;
        } else if a[i]==i {
            if !set.contains(&a[i]) {
                cnt+=1;
                set.insert(a[i]);
            }
            ans*=cnt;
            cnt-=1;
        } else if !set.contains(&a[i]) {
            cnt+=1;
            set.insert(a[i]);
        }
    }
    if cnt>0 {
        ans*=0;
    }
    outputln!(ans);
}

C問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use proconio::marker::Usize1;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(n:usize,uv:[(Usize1,Usize1);n-1]);
    let g=VecGraph::construct_graph(n, n-1, &uv);
    let mut seen=vec![false;n];
    seen[0]=true;
    let mut deg=vec![0;n];
    let mut dp=vec![vec![Mint::new(0);n];n];
    dfs(0, n, &g, &mut seen, &mut deg, &mut dp);
    outputln!(dp[0].sum());
}

fn dfs(v: usize, n: usize, g: &VecGraph, seen: &mut Vec<bool>, deg: &mut Vec<usize>, dp: &mut Vec<Vec<Mint>>) {
    dp[v][0]+=1;
    for &(u,_) in &g.get()[v] {
        if seen[u] {
            continue;
        }
        seen[u]=true;
        deg[v]+=1;
        dfs(u, n, g, seen, deg, dp);
        let mut new=vec![Mint::new(0);n];
        for i in 0..deg[v] {
            for j in 0..=deg[u] {
                new[i+1]+=dp[v][i]*(i+1)*dp[u][j]*(j+1);
                new[i]+=dp[v][i]*dp[u][j];
            }
        }
        dp[v]=new;
    }
}

D問題

atcoder.jp
atcoder.jp

#[allow(unused_attributes)] #[macro_use] #[allow(unused_imports)] use not_leonian_ac_lib::*;
use proconio::marker::Usize1;

fn main() {
    /// 標準入力のマクロ(インタラクティブ問題ならば中のマクロを変更)
    macro_rules! input {
        ($($tt:tt)*) => {
            proconio::input!($($tt)*);
            // proconio::input_interactive!($($tt)*);
        };
    }

    input!(p:usize,_:usize,n:usize,m:usize,lr:[(Usize1,usize);m]);
    let g=VecGraph::construct_graph(n+1, m, &lr);
    output_yes_or_no(g.chromatic_number()<=p);
}