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 Kotlin (1.0.0) (judge verdict: Accepted)

import java.io.BufferedReader
import java.io.InputStreamReader
import java.util.*

fun main(array: Array<String>) {
    val jin = BufferedReader(InputStreamReader(System.`in`))
    var tokenizer = StringTokenizer(jin.readLine())
    val n = tokenizer.nextToken().toInt()
    val k = tokenizer.nextToken().toInt()
    tokenizer = StringTokenizer(jin.readLine())
    val p = IntArray(n) { tokenizer.nextToken().toInt() }
    val dp = IntArray(n) { 1 }
    for (j in n - 2 downTo 0) {
        if (p[j] < p[j + 1]) {
            dp[j] = dp[j + 1] + 1
        }
    }
    val minSegTree = MinSegmentTree(0, n - 1)
    val maxSegTree = MaxSegmentTree(0, n - 1)
    for (j in 0 until n) {
        minSegTree.update(j, p[j])
        maxSegTree.update(j, p[j])
    }
    var answer = 1
    var foundOriginal = dp[0] >= k
    for (j in 0 until n - k) {
        if (p[j] > minSegTree.query(j + 1, j + k - 1) || p[j + k] < maxSegTree.query(j + 1, j + k - 1)) {
            if (dp[j + 1] >= k) {
                if (!foundOriginal) {
                    foundOriginal = true
                    //println("j = $j")
                    answer++
                } else {
                    //println("j = $j already found original")
                }
            } else {
                //println("j = $j")
                answer++
            }
        }
    }
    println(answer)
}

class MaxSegmentTree(val treeFrom: Int, treeTo: Int) {
    val `val`: IntArray
    val length: Int
    fun update(index: Int, delta: Int) {
        var node = index - treeFrom + length
        `val`[node] = delta
        node = node shr 1
        while (node > 0) {
            `val`[node] = Math.max(`val`[node shl 1], `val`[(node shl 1) + 1])
            node = node shr 1
        }
    }

    fun query(from: Int, to: Int): Int {
        var from = from
        var to = to
        if (to < from) {
            return 0
        }
        from += length - treeFrom
        to += length - treeFrom + 1
        var res = 0
        while (from + (from and -from) <= to) {
            res = Math.max(res, `val`[from / (from and -from)])
            from += from and -from
        }
        while (to - (to and -to) >= from) {
            res = Math.max(res, `val`[(to - (to and -to)) / (to and -to)])
            to -= to and -to
        }
        return res
    }

    init {
        val length = treeTo - treeFrom + 1
        var l: Int
        l = 0
        while (1 shl l < length) {
            l++
        }
        `val` = IntArray(1 shl l + 1)
        this.length = 1 shl l
    }
}

class MinSegmentTree(val treeFrom: Int, treeTo: Int) {
    val `val`: IntArray
    val length: Int
    fun update(index: Int, delta: Int) {
        var node = index - treeFrom + length
        `val`[node] = delta
        node = node shr 1
        while (node > 0) {
            `val`[node] = Math.min(`val`[node shl 1], `val`[(node shl 1) + 1])
            node = node shr 1
        }
    }

    fun query(from: Int, to: Int): Int {
        var from = from
        var to = to
        if (to < from) {
            return 0
        }
        from += length - treeFrom
        to += length - treeFrom + 1
        var res = Int.MAX_VALUE
        while (from + (from and -from) <= to) {
            res = Math.min(res, `val`[from / (from and -from)])
            from += from and -from
        }
        while (to - (to and -to) >= from) {
            res = Math.min(res, `val`[(to - (to and -to)) / (to and -to)])
            to -= to and -to
        }
        return res
    }

    init {
        val length = treeTo - treeFrom + 1
        var l: Int
        l = 0
        while (1 shl l < length) {
            l++
        }
        `val` = IntArray(1 shl l + 1)
        this.length = 1 shl l
    }
}