AtCoder Beginner Contest 461 D

https://atcoder.jp/contests/abc461/tasks/abc461_d

何行目から何行目かを固定して、何列目から何列目まででKになるパターンを数えます。全部0以上なので、尺取り法的に数えられて、計算量は O(N^3)でなんとか間に合います。
ただし、K=0のときうまくいかないので、単にその幅で全部0になる列の並びを見つければよいです。

// Count Subgrid Sum = K
#![allow(non_snake_case)]


//////////////////// library ////////////////////

fn read<T: std::str::FromStr>() -> T {
    let mut line = String::new();
    std::io::stdin().read_line(&mut line).ok();
    line.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>().split_whitespace()
            .map(|e| e.parse().ok().unwrap()).collect()
}


//////////////////// process ////////////////////

fn read_input() -> (i32, Vec<String>) {
    let v: Vec<usize> = read_vec();
    let (H, K) = (v[0], v[2] as i32);
    let S: Vec<String> = (0..H).map(|_| read()).collect();
    (K, S)
}

fn create_table(S: Vec<String>) -> Vec<Vec<i32>> {
    S.into_iter().map(|s| s.chars().
                            map(|c| (c == '1') as i32).collect()).
                    collect::<Vec<Vec<i32>>>()
}

fn accumulate_2D(table: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
    let H = table.len();
    let W = table[0].len();
    let mut acc: Vec<Vec<i32>> = vec![vec![0; W+1]; H+1];
    for i in 1..H+1 {
        for j in 1..W+1 {
            acc[i][j] = acc[i][j-1] + acc[i-1][j] - acc[i-1][j-1]
                                                 + table[i-1][j-1]
        }
    }
    acc
}

fn groupby(v: &Vec<i32>) -> Vec<(i32, usize)> {
    let mut w: Vec<(i32, usize)> = vec![];
    let mut n: usize = 0;
    let mut prev: i32 = -1;
    for &e in v.iter() {
        if e != prev && n != 0 {
            w.push((prev, n));
            n = 0
        }
        prev = e;
        n += 1
    }
    w.push((prev, n));
    w
}

fn F_each(i1: usize, i2: usize, K: i32, table: &Vec<Vec<i32>>) -> usize {
    let L = table[0].len();
    let acc: Vec<i32> = (0..L).map(|j| table[i2][j] - table[i1][j]).collect();
    let g = groupby(&acc);
    let mut counter: usize = 0;
    let mut j: usize = 0;
    let mut k: usize = 1;
    while k < g.len() {
        let (e1, n1) = g[j];
        let (e2, n2) = g[k];
        if e2 - e1 == K {
            if j == k {
                counter += n1 * (n1 + 1) / 2
            }
            else {
                counter += n1 * n2
            }
            j += 1;
            k += 1
        }
        else if e2 - e1 > K {
            j += 1
        }
        else {
            k += 1
        }
    }
    counter
}

fn F_each0(acc: &Vec<i32>) -> usize {
    let g = groupby(&acc);
    g.into_iter().filter(|&(e, _)| e == 0).
                    map(|(_, n)| n*(n+1)/2).sum::<usize>()
}

fn F0(table: Vec<Vec<i32>>) -> usize {
    let mut counter: usize = 0;
    let H = table.len();
    let W = table[0].len();
    for i1 in 0..H {
        let mut acc: Vec<i32> = vec![0; W];
        for i2 in i1..H {
            for j in 0..W {
                acc[j] |= table[i2][j]
            }
            counter += F_each0(&acc)
        }
    }
    counter
}

fn F(K: i32, S: Vec<String>) -> usize {
    let H = S.len();
    let table = create_table(S);
    if K == 0 {
        return F0(table)
    }
    
    let acc_table = accumulate_2D(table);
    let mut counter: usize = 0;
    for i1 in 0..H {
        for i2 in i1+1..H+1 {
            counter += F_each(i1, i2, K, &acc_table)
        }
    }
    counter
}

fn main() {
    let (K, S) = read_input();
    println!("{}", F(K, S))
}