记 sum[k][i] 表示 k 维前缀和的第 i 项,比如:
sum[0] = 0, 1, 0, 0
sum[1] = 0, 1, 1, 1
sum[2] = 0, 1, 2, 3
sum[3] = 0, 1, 3, 6, …
那么答案就是 sigma(sum[i+2][ai]).
高维前缀和单点可以用组合数求,sum(k,n) = C(n+k-2, n-1),放到答案里也就是 sigma(C(i+ai, i+1)).
相关的具体说明有个 quora 答案写的挺好:https://qr.ae/pvo6rl
组合数可以使用经典预处理阶乘+逆元去做。
很早就想到了做法,然后找板子写板子写了好久,结束之后才写完,错过了上分机会,令人感叹。
https://oi-wiki.org/math/number-theory/inverse/
#[allow(unused_imports)]
use std::io::{BufWriter, stdin, stdout, Write};
#[derive(Default)]
struct Scanner {
buffer: Vec<String>
}
impl Scanner {
fn next<T: std::str::FromStr>(&mut self) -> T {
loop {
if let Some(token) = self.buffer.pop() {
return token.parse().ok().expect("Failed parse");
}
let mut input = String::new();
stdin().read_line(&mut input).expect("Failed read");
self.buffer = input.split_whitespace().rev().map(String::from).collect();
}
}
#[allow(dead_code)]
fn next_n<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
(0..n).map(|_| self.next::<T>()).collect()
}
}
//
// fn naive_cal(k: i32, n: i32) -> i32 {
// if k == 0 {
// return n;
// }
// let mut ans = 0;
// for i in 1..=n {
// ans += naive_cal(k - 1, i);
// }
// ans
// }
//
// fn naive_c(a: i64, b: i64) -> i64 {
// // println!("a={} b={}", a, b);
// let mut res = 1;
// for i in (a-b+1)..=a {
// res *= i;
// }
// for i in 1..=b {
// res /= i;
// }
//
// res
// }
struct MathSolver {
fac: Vec<i64>,
}
impl MathSolver {
const MOD: i64 = 1000000007;
fn new(mx: usize) -> Self {
let mut fac = vec![1i64; mx];
for i in 1..mx {
fac[i] = (fac[i-1] * i as i64) % Self::MOD;
}
Self { fac }
}
// solve ax+by=gcd(a,b)
fn exgcd(a: i64, b: i64) -> (i64, i64) {
if b == 0 {
return (1, 0);
}
let (x, y) = Self::exgcd(b, a % b);
(y, x - a / b * y)
}
fn normalize(a: i64) -> i64 {
(a % Self::MOD + Self::MOD) % Self::MOD
}
// solve ax===1 (mod b)
fn inv(&self, a: i64) -> i64{
Self::normalize(Self::exgcd(a, Self::MOD).0)
}
fn c(&self, a: usize, b: usize) -> i64 {
self.fac[a] * self.inv(self.fac[b] * self.fac[a-b] % Self::MOD) % Self::MOD
}
}
fn work(n: usize, a: Vec<usize>) -> i64 {
let solver = MathSolver::new(500000);
let mut ans = 0;
for i in 0..=n {
if a[i] != 0 {
ans += solver.c(i + a[i], i + 1);
ans %= 1000000007;
}
}
ans
}
fn main() {
let mut scanner = Scanner::default();
let out = &mut BufWriter::new(stdout());
// let t = scanner.next::<usize>();
// for _ in 0..t {
let n = scanner.next::<usize>();
let a = scanner.next_n::<usize>(n+1);
let res = work(n, a);
writeln!(out, "{}", res).ok();
// }
}
#[test]
fn test() {
}