Problem:
Score : 700 points

Problem Statement

Snuke has a permutation (P_0,P_1,\cdots,P_{N-1}) of (0,1,\cdots,N-1).

Now, he will perform the following operation exactly once:

Choose K consecutive elements in P and sort them in ascending order.

Find the number of permutations that can be produced as P after the operation.

Constraints

2 \leq N \leq 200000

2 \leq K \leq N

0 \leq P_i \leq N-1

P_0,P_1,\cdots,P_{N-1} are all different.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N K
P_0 P_1 \cdots P_{N-1}

Output

Print the number of permutations that can be produced as P after the operation.

Sample Input 1

5 3
0 2 1 4 3

Sample Output 1

2

Two permutations can be produced as P after the operation: (0,1,2,4,3) and (0,2,1,3,4).

Sample Input 2

4 4
0 1 2 3

Sample Output 2

1

Sample Input 3

10 4
2 0 1 3 7 5 4 6 8 9

Sample Output 3

6

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

/*------------------------------------------------------------------*/
/*------------------------- begin template -------------------------*/
/*------------------------------------------------------------------*/

// ref: tanakh <https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8>
// diff: using Parser
macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut parser = Parser::from_str($s);
        input_inner!{parser, $($r)*}
    };
    (parser = $parser:ident, $($r:tt)*) => {
        input_inner!{$parser, $($r)*}
    };
    (new_stdin_parser = $parser:ident, $($r:tt)*) => {
        let stdin = std::io::stdin();
        let reader = std::io::BufReader::new(stdin.lock());
        let mut $parser = Parser::new(reader);
        input_inner!{$parser, $($r)*}
    };
    ($($r:tt)*) => {
        input!{new_stdin_parser = parser, $($r)*}
    };
}

macro_rules! input_inner {
    ($parser:ident) => {};
    ($parser:ident, ) => {};
    ($parser:ident, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($parser, $t);
        input_inner!{$parser $($r)*}
    };
}

macro_rules! read_value {
    ($parser:ident, ( $($t:tt),* )) => {
        ( $(read_value!($parser, $t)),* )
    };
    ($parser:ident, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($parser, $t)).collect::<Vec<_>>()
    };
    ($parser:ident, chars) => {
        read_value!($parser, String).chars().collect::<Vec<char>>()
    };
    ($parser:ident, char_) => {
        read_value!($parser, String).chars().collect::<Vec<char>>()[0]
    };
    ($parser:ident, usize1) => {
        read_value!($parser, usize) - 1
    };
    ($parser:ident, i64_) => {
        $parser.fast_i64()
    };
    ($parser:ident, usize_) => {
        $parser.fast_i64() as usize
    };
    ($parser:ident, usize1_) => {
        ($parser.fast_i64() - 1) as usize
    };
    ($parser:ident, $t:ty) => {
        $parser.next::<$t>().expect("Parse error")
    };
}

use std::io;
use std::io::BufRead;
use std::str;

// ref: tatsuya6502 <https://qiita.com/tatsuya6502/items/cd448486f7ef7b5b8c7e>
// ref: wariuni <https://qiita.com/tatsuya6502/items/cd448486f7ef7b5b8c7e#comment-7040a5ae96305e884eb9>
// diff: using std::io::BufRead::fill_buf()
pub struct Parser<R> {
    pub reader: R,
    buf: Vec<u8>,
    pos: usize,
}

impl Parser<io::Empty> {
    pub fn from_str(s: &str) -> Parser<io::Empty> {
        Parser {
            reader: io::empty(),
            buf: s.as_bytes().to_vec(),
            pos: 0,
        }
    }
}

impl<R: BufRead> Parser<R> {
    pub fn new(reader: R) -> Parser<R> {
        Parser {
            reader: reader,
            buf: vec![],
            pos: 0,
        }
    }
    pub fn update_buf(&mut self) {
        self.buf.clear();
        self.pos = 0;
        loop {
            let (len, complete) = {
                let buf2 = self.reader.fill_buf().unwrap();
                self.buf.extend_from_slice(buf2);
                let len = buf2.len();
                (len, buf2[len - 1] <= 0x20)
            };
            self.reader.consume(len);
            if complete {
                break;
            }
        }
    }
    pub fn next<T: str::FromStr>(&mut self) -> Result<T, T::Err> {
        loop {
            let mut begin = self.pos;
            while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                begin += 1;
            }
            let mut end = begin;
            while end < self.buf.len() && (self.buf[end] > 0x20) {
                end += 1;
            }
            if begin != self.buf.len() {
                self.pos = end;
                return unsafe { str::from_utf8_unchecked(&self.buf[begin..end]) }.parse::<T>();
            } else {
                self.update_buf();
            }
        }
    }
    pub fn fast_i64(&mut self) -> i64 {
        loop {
            let mut begin = self.pos;
            while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                begin += 1;
            }
            if begin == self.buf.len() {
                self.update_buf();
                continue;
            }
            let mut res = 0;
            let (is_positive, mut end) = match self.buf[begin] {
                b'+' => (true, begin + 1),
                b'-' => (false, begin + 1),
                _ => (true, begin),
            };
            while end < self.buf.len() && (self.buf[end] > 0x20) {
                res = res * 10 + (self.buf[end] as i64 - '0' as i64);
                end += 1;
            }
            if begin != self.buf.len() {
                self.pos = end;
                return if is_positive { res } else { -res };
            } else {
                self.update_buf();
            }
        }
    }
}

#[allow(unused_imports)]
use std::cmp::*;

#[derive(Debug, Default)]
pub struct MySet<T> {
    root: Option<Box<MySetNode<T>>>,
}

#[derive(Debug)]
enum MySetNode<T> {
    Node {
        left_node: Box<MySetNode<T>>,
        right_node: Box<MySetNode<T>>,
        lower: T,
        upper: T,
        rank: usize,
        num: usize,
    },
    Leaf {
        val: T,
    },
}

impl<T: Clone + Copy + PartialEq + Eq + PartialOrd + Ord + std::fmt::Debug> MySet<T> {
    pub fn new() -> MySet<T> {
        MySet { root: None }
    }
    pub fn insert(&mut self, x: T) {
        *self = match self.root.take() {
            Some(root) => MySet {
                root: Some(Box::new(MySetNode::insert(*root, x))),
            },
            None => MySet {
                root: Some(Box::new(MySetNode::Leaf { val: x })),
            },
        };
    }
    pub fn delete(&mut self, x: T) {
        *self = match self.root.take() {
            Some(root) => {
                let root = MySetNode::delete(*root, x);
                match root {
                    Some(root) => MySet {
                        root: Some(Box::new(root)),
                    },
                    None => MySet { root: None },
                }
            }
            None => MySet { root: None },
        };
    }
    pub fn next(&self, x: T) -> Option<T> {
        match *&self.root {
            Some(ref root) => MySetNode::next(root.as_ref(), x),
            None => None,
        }
    }
    pub fn prev(&self, x: T) -> Option<T> {
        match *&self.root {
            Some(ref root) => MySetNode::prev(root.as_ref(), x),
            None => None,
        }
    }
    pub fn lower(&self) -> Option<T> {
        match *&self.root {
            Some(ref root) => Some(root.get_lower()),
            None => None,
        }
    }
    pub fn upper(&self) -> Option<T> {
        match *&self.root {
            Some(ref root) => Some(root.get_upper()),
            None => None,
        }
    }
}

impl<T: Clone + Copy + PartialEq + Eq + PartialOrd + Ord + std::fmt::Debug> MySetNode<T> {
    fn new(left: MySetNode<T>, right: MySetNode<T>) -> MySetNode<T> {
        // assert!(left.rank() + 1 == right.rank() || left.rank() == right.rank() || left.rank() == right.rank() + 1, "left = {:?}, right = {:?}", left, right);
        let lower = left.get_lower();
        let upper = right.get_upper();
        let rank = 1 + max(left.rank(), right.rank());
        let num = left.num() + right.num();
        MySetNode::Node {
            left_node: Box::new(left),
            right_node: Box::new(right),
            lower: lower,
            upper: upper,
            rank: rank,
            num: num,
        }
    }
    fn get_lower(&self) -> T {
        match *self {
            MySetNode::Node { ref lower, .. } => *lower,
            MySetNode::Leaf { ref val } => *val,
        }
    }
    fn get_upper(&self) -> T {
        match *self {
            MySetNode::Node { ref upper, .. } => *upper,
            MySetNode::Leaf { ref val } => *val,
        }
    }
    fn rank(&self) -> usize {
        match *self {
            MySetNode::Node { ref rank, .. } => *rank,
            MySetNode::Leaf { val: _ } => 1,
        }
    }
    fn num(&self) -> usize {
        match *self {
            MySetNode::Node { ref num, .. } => *num,
            MySetNode::Leaf { val: _ } => 1,
        }
    }
    fn get_left_rank(&self) -> usize {
        match *self {
            MySetNode::Node { ref left_node, .. } => left_node.rank(),
            _ => 0,
        }
    }
    fn get_right_rank(&self) -> usize {
        match *self {
            MySetNode::Node { ref right_node, .. } => right_node.rank(),
            _ => 0,
        }
    }
    fn unsafe_destruct(node: MySetNode<T>) -> (MySetNode<T>, MySetNode<T>) {
        match node {
            MySetNode::Node {
                left_node,
                right_node,
                ..
            } => (*left_node, *right_node),
            _ => panic!(),
        }
    }

    fn balance2(left_node: MySetNode<T>, right_node: MySetNode<T>) -> MySetNode<T> {
        if left_node.rank() >= right_node.rank() + 2 {
            if left_node.get_left_rank() >= left_node.get_right_rank() {
                let (node_l, node_r) = (left_node, right_node);
                let (node_ll, node_lr) = MySetNode::unsafe_destruct(node_l);
                MySetNode::new(node_ll, MySetNode::new(node_lr, node_r))
            } else {
                let (node_l, node_r) = (left_node, right_node);
                let (node_ll, node_lr) = MySetNode::unsafe_destruct(node_l);
                let (node_lrl, node_lrr) = MySetNode::unsafe_destruct(node_lr);
                MySetNode::new(
                    MySetNode::new(node_ll, node_lrl),
                    MySetNode::new(node_lrr, node_r),
                )
            }
        } else if left_node.rank() + 2 <= right_node.rank() {
            if right_node.get_left_rank() >= right_node.get_right_rank() {
                let (node_l, node_r) = (left_node, right_node);
                let (node_rl, node_rr) = MySetNode::unsafe_destruct(node_r);
                let (node_rll, node_rlr) = MySetNode::unsafe_destruct(node_rl);
                MySetNode::new(
                    MySetNode::new(node_l, node_rll),
                    MySetNode::new(node_rlr, node_rr),
                )
            } else {
                let (node_l, node_r) = (left_node, right_node);
                let (node_rl, node_rr) = MySetNode::unsafe_destruct(node_r);
                MySetNode::new(MySetNode::new(node_l, node_rl), node_rr)
            }
        } else {
            MySetNode::new(left_node, right_node)
        }
    }

    fn insert(node: MySetNode<T>, x: T) -> MySetNode<T> {
        match node {
            MySetNode::Node {
                left_node,
                right_node,
                ..
            } => {
                if x < right_node.get_lower() {
                    let left_node = MySetNode::insert(*left_node, x);
                    MySetNode::balance2(left_node, *right_node)
                } else {
                    let right_node = MySetNode::insert(*right_node, x);
                    MySetNode::balance2(*left_node, right_node)
                }
            }
            MySetNode::Leaf { val } => match val.cmp(&x) {
                Ordering::Less => {
                    MySetNode::new(MySetNode::Leaf { val: val }, MySetNode::Leaf { val: x })
                }
                Ordering::Equal => MySetNode::Leaf { val: x },
                Ordering::Greater => {
                    MySetNode::new(MySetNode::Leaf { val: x }, MySetNode::Leaf { val: val })
                }
            },
        }
    }
    fn delete(node: MySetNode<T>, x: T) -> Option<MySetNode<T>> {
        match node {
            MySetNode::Node {
                left_node,
                right_node,
                ..
            } => {
                if left_node.get_lower() <= x && x <= left_node.get_upper() {
                    let left_node = MySetNode::delete(*left_node, x);
                    match left_node {
                        Some(left_node) => Some(MySetNode::balance2(left_node, *right_node)),
                        None => Some(*right_node),
                    }
                } else if right_node.get_lower() <= x && x <= right_node.get_upper() {
                    let right_node = MySetNode::delete(*right_node, x);
                    match right_node {
                        Some(right_node) => Some(MySetNode::balance2(*left_node, right_node)),
                        None => Some(*left_node),
                    }
                } else {
                    Some(MySetNode::new(*left_node, *right_node))
                }
            }
            MySetNode::Leaf { val } => match val.cmp(&x) {
                Ordering::Less => Some(MySetNode::Leaf { val: x }),
                Ordering::Equal => None,
                Ordering::Greater => Some(MySetNode::Leaf { val: x }),
            },
        }
    }
    fn next(node: &MySetNode<T>, x: T) -> Option<T> {
        match *node {
            MySetNode::Node {
                ref left_node,
                ref right_node,
                ..
            } => {
                if right_node.get_lower() <= x {
                    MySetNode::next(right_node, x)
                } else {
                    let t = MySetNode::next(left_node, x);
                    if t.is_some() {
                        t
                    } else {
                        Some(right_node.get_lower())
                    }
                }
            }
            MySetNode::Leaf { ref val } => {
                if x < *val {
                    Some(*val)
                } else {
                    None
                }
            }
        }
    }
    fn prev(node: &MySetNode<T>, x: T) -> Option<T> {
        match *node {
            MySetNode::Node {
                ref left_node,
                ref right_node,
                ..
            } => {
                if x <= left_node.get_upper() {
                    MySetNode::prev(left_node, x)
                } else {
                    let t = MySetNode::prev(right_node, x);
                    if t.is_some() {
                        t
                    } else {
                        Some(left_node.get_upper())
                    }
                }
            }
            MySetNode::Leaf { val: ref val } => {
                if *val < x {
                    Some(*val)
                } else {
                    None
                }
            }
        }
    }
}

pub fn permutations<T: Copy>(xs: &Vec<T>) -> Vec<Vec<T>> {
    let mut buf = vec![];
    let mut used = vec![false; xs.len()];
    let mut tmp = vec![];
    permutations_sub(xs, &mut used, &mut buf, &mut tmp, 0);
    buf
}

fn permutations_sub<T: Copy>(
    xs: &Vec<T>,
    used: &mut Vec<bool>,
    buf: &mut Vec<Vec<T>>,
    tmp: &mut Vec<T>,
    i: usize,
) {
    if i == xs.len() {
        buf.push(tmp.clone());
        return;
    }
    for k in 0..xs.len() {
        if used[k] {
            continue;
        }
        used[k] = true;
        tmp.push(xs[k]);
        permutations_sub(xs, used, buf, tmp, i + 1);
        tmp.pop();
        used[k] = false;
    }
}

fn main() {
    input! {
        new_stdin_parser = parser,
    }
    let res = solve(&mut parser);
    print!("{}", res);
}

/*------------------------------------------------------------------*/
/*-------------------------- end template --------------------------*/
/*------------------------------------------------------------------*/

use std::fmt::Write;

fn f(n: usize, m: usize, xs: &[i64]) -> i64 {
    let mut inc_count = vec![0; n];
    inc_count[0] = 1;
    for i in 1..n {
        if xs[i - 1] < xs[i] {
            inc_count[i] += inc_count[i - 1] + 1;
        } else {
            inc_count[i] = 1;
        }
    }
    let mut res = (n - m + 1) as i64;
    let mut res2 = 0;
    if inc_count[m - 1] >= m {
        res2 += 1;
    }
    let mut set = MySet::new();
    for i in 0..m {
        set.insert(xs[i]);
    }
    for i in m..n {
        let pop_i = i - m;
        let push_i = i;
        let a = xs[pop_i];
        set.delete(a);
        let b_min = set.lower().unwrap();
        let b_max = set.upper().unwrap();
        let c = xs[push_i];
        if a < b_min && b_max < c {
            res -= 1;
        } else if inc_count[i] >= m {
            res2 += 1;
        }
        set.insert(c);
    }
    // eprintln!("res = {}, res2 = {}", res, res2);
    let res = res - max(0, res2 - 1);
    res
}

fn g(n: usize, m: usize, xs: &[i64]) -> i64 {
    let mut ys = vec![];
    for i in m..n + 1 {
        let mut zs = vec![];
        for k in 0..i - m {
            zs.push(xs[k]);
        }
        let mut ts = vec![];
        for k in i - m..i {
            ts.push(xs[k]);
        }
        ts.sort();
        for &t in &ts {
            zs.push(t);
        }
        for k in i..n {
            zs.push(xs[k]);
        }
        ys.push(zs);
    }
    ys.sort();
    // eprintln!("ys2 = {:?}", ys);
    let mut res = ys.len() as i64;
    for i in 1..ys.len() {
        if ys[i - 1] == ys[i] {
            res -= 1;
        }
    }
    res
}

fn test() {
    let n = 6;
    let m = 2;
    let mut xs: Vec<i64> = (0..n).map(|x| x as i64).collect();
    let perms = permutations(&xs);
    for perm in &perms {
        assert_eq!(f(n, m, perm), g(n, m, perm), "prem = {:?}", perm);
    }
}

fn solve<R: BufRead>(parser: &mut Parser<R>) -> String {
    let mut buf = String::new();
    input! {
        parser = parser,
        n: usize,
        m: usize,
        xs: [i64; n],
    }

    // test();

    let res = f(n, m, &xs);
    writeln!(buf, "{}", res);
    buf
}