Problem:
Score : 600 points

Problem Statement

Find the number of sequences of length K consisting of positive integers such that the product of any two adjacent elements is at most N, modulo 10^9+7.

Constraints

1\leq N\leq 10^9

1 2\leq K\leq 100 (fixed at 21:33 JST)

N and K are integers.

Input

Input is given from Standard Input in the following format:

N K

Output

Print the number of sequences, modulo 10^9+7.

Sample Input 1

3 2

Sample Output 1

5

(1,1), (1,2), (1,3), (2,1), and (3,1) satisfy the condition.

Sample Input 2

10 3

Sample Output 2

147

Sample Input 3

314159265 35

Sample Output 3

457397712

Solution in Rust (1.15.1) (judge verdict: Accepted)

use std::io::prelude::*;

fn input<T: std::str::FromStr>() -> T {
    let stdin = std::io::stdin();
    let token: String = stdin
        .lock()
        .bytes()
        .map(|c| c.unwrap() as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().unwrap()
}

fn main() {
    let n: i64 = input();
    let k: i64 = input();

    ModInt::set_mod(1000000007);

    let mut s = vec![];
    for i in 1.. {
        if i * i > n {
            break;
        }
        s.push(i);
        s.push(n / i);
    }
    s.sort();
    s.dedup();

    let m = s.len();
    let mut w = vec![1; m];
    for i in 0..m - 1 {
        w[i] = n / s[i] - n / s[i + 1];
    }

    let mut dp = vec![vec![ModInt(0); m]; k as usize + 1];
    dp[0][m - 1] += 1;
    for i in 0..k as usize {
        for j in (0..m - 1).rev() {
            let t = dp[i][j + 1];
            dp[i][j] += t;
        }
        for j in 0..m {
            let nj = s.lower_bound(n / s[j]);
            let t = dp[i][nj] * w[j];
            dp[i + 1][j] += t;
        }
    }

    println!("{}", dp[k as usize].iter().sum::<ModInt>());
}

trait LowerBound<T: Ord> {
    fn lower_bound(&self, x: T) -> usize;
}

impl<T: Ord> LowerBound<T> for [T] {
    fn lower_bound(&self, x: T) -> usize {
        let mut l = -1 as i64;
        let mut r = self.len() as i64;
        while r - l > 1 {
            let m = ((l + r) / 2) as usize;
            if self[m] >= x {
                r = m as i64;
            } else {
                l = m as i64;
            }
        }
        r as usize
    }
}

static mut MOD: i64 = 0;

#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
struct ModInt(i64);

impl ModInt {
    fn new(x: i64) -> ModInt {
        let m = ModInt::get_mod();
        ModInt(if x < m { x } else { x % m })
    }

    fn get_mod() -> i64 {
        unsafe { MOD }
    }

    fn set_mod(x: i64) {
        unsafe {
            MOD = x;
        }
    }
}

impl std::fmt::Display for ModInt {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.0.fmt(f)
    }
}

impl std::ops::AddAssign<ModInt> for ModInt {
    fn add_assign(&mut self, other: ModInt) {
        let m = ModInt::get_mod();
        self.0 += other.0;
        if self.0 >= m {
            self.0 -= m;
        }
    }
}

impl std::ops::MulAssign<ModInt> for ModInt {
    fn mul_assign(&mut self, other: ModInt) {
        let m = ModInt::get_mod();
        self.0 *= other.0;
        if self.0 >= m {
            self.0 %= m;
        }
    }
}

impl std::ops::SubAssign<ModInt> for ModInt {
    fn sub_assign(&mut self, other: ModInt) {
        let m = ModInt::get_mod();
        self.0 += m - other.0;
        if self.0 >= m {
            self.0 -= m;
        }
    }
}

macro_rules! impl_modint_assign_op_ref {
    ($imp:ident, $method:ident) => {
        impl<'a> std::ops::$imp<&'a ModInt> for ModInt {
            fn $method(&mut self, other: &'a ModInt) {
                std::ops::$imp::$method(self, *other);
            }
        }
    };
}

impl_modint_assign_op_ref!(AddAssign, add_assign);
impl_modint_assign_op_ref!(MulAssign, mul_assign);
impl_modint_assign_op_ref!(SubAssign, sub_assign);

macro_rules! impl_modint_op {
    ($imp:ident, $method:ident, $assign_t:ident, $assign_m:ident) => {
        impl std::ops::$imp<ModInt> for ModInt {
            type Output = ModInt;

            fn $method(self, other: ModInt) -> ModInt {
                let mut x = self;
                std::ops::$assign_t::$assign_m(&mut x, other);
                x
            }
        }
    };
}

impl_modint_op!(Add, add, AddAssign, add_assign);
impl_modint_op!(Mul, mul, MulAssign, mul_assign);
impl_modint_op!(Sub, sub, SubAssign, sub_assign);

macro_rules! impl_modint_op_ref {
    ($imp:ident, $method:ident) => {
        impl<'a> std::ops::$imp<ModInt> for &'a ModInt {
            type Output = ModInt;

            fn $method(self, other: ModInt) -> ModInt {
                std::ops::$imp::$method(*self, other)
            }
        }

        impl<'a> std::ops::$imp<&'a ModInt> for ModInt {
            type Output = ModInt;

            fn $method(self, other: &'a ModInt) -> ModInt {
                std::ops::$imp::$method(self, *other)
            }
        }

        impl<'a, 'b> std::ops::$imp<&'b ModInt> for &'a ModInt {
            type Output = ModInt;

            fn $method(self, other: &'b ModInt) -> ModInt {
                std::ops::$imp::$method(*self, *other)
            }
        }
    };
}

impl_modint_op_ref!(Add, add);
impl_modint_op_ref!(Mul, mul);
impl_modint_op_ref!(Sub, sub);

macro_rules! impl_modint_op_i64 {
    ($imp:ident, $method:ident) => {
        impl<T: Into<i64>> std::ops::$imp<T> for ModInt {
            type Output = ModInt;

            fn $method(self, other: T) -> ModInt {
                std::ops::$imp::$method(self, ModInt::new(other.into()))
            }
        }
    };
}

impl_modint_op_i64!(Add, add);
impl_modint_op_i64!(Mul, mul);
impl_modint_op_i64!(Sub, sub);

macro_rules! impl_modint_assign_op_i64 {
    ($imp:ident, $method:ident) => {
        impl<T: Into<i64>> std::ops::$imp<T> for ModInt {
            fn $method(&mut self, other: T) {
                std::ops::$imp::$method(self, ModInt::new(other.into()));
            }
        }
    };
}

impl_modint_assign_op_i64!(AddAssign, add_assign);
impl_modint_assign_op_i64!(MulAssign, mul_assign);
impl_modint_assign_op_i64!(SubAssign, sub_assign);

macro_rules! impl_modint_accum {
    ($imp:ident, $method:ident, $id:expr, $op_t:ident, $op_m:ident) => {
        impl std::iter::$imp for ModInt {
            fn $method<I: Iterator<Item = ModInt>>(iter: I) -> ModInt {
                iter.fold(ModInt($id), std::ops::$op_t::$op_m)
            }
        }

        impl<'a> std::iter::$imp<&'a ModInt> for ModInt {
            fn $method<I: Iterator<Item = &'a ModInt>>(iter: I) -> ModInt {
                iter.fold(ModInt($id), std::ops::$op_t::$op_m)
            }
        }
    };
}

impl_modint_accum!(Sum, sum, 0, Add, add);
impl_modint_accum!(Product, product, 1, Mul, mul);