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 C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Collections.Generic;
using System.Linq;

class Program
{
    //static int[] dp;
    //static decimal[,,] dp;
    //static decimal N;
    static void Main(string[] args)
    {
        // 入力
        int[] input = Console.ReadLine().Split().Select(p => int.Parse(p)).ToArray();
        int N = input[0];
        int K = input[1];
        input = Console.ReadLine().Split().Select(p => int.Parse(p)).ToArray();

        // 連続したK個の区間が昇順になっているもののスタート地点
        HashSet<int> hs = getSuccess(input, K);
        
        // １～K-2番目をソートしたもの
        List<int> firstK = getFirstK(input, 1, K-1);

        int ret = 1;
        int min = firstK[0];
        int max = firstK[K - 2];
        for (int i=0; i+K < N; i++)
        {
            // i番目とi+1番目が両方hsに入ってる＝昇順
            bool first = hs.Contains(i);
            bool second = hs.Contains(i + 1);
            if(first)
            {
                continue;
            }

            // i番目からk個を並び替える場合と、i+1番目からK個を並び替える場合が
            // 並び替えた後の数列が一致するなら増やさない、一致しないなら増やす
            if (input[i] < min && input[i + K] > max)
            {
                // 一致する
            }
            else
            {
                ret++;
            }

            // input[i+1]が抜けて、input[i+K]が加わる
            firstK.Remove(input[i + 1]);
            firstK.Add(input[i + K]);
            firstK.Sort();
            min = firstK[0];
            max = firstK[K - 2];

        }

        Console.WriteLine(ret + "");

        
    }

    private static List<int> getFirstK(int[] input, int start, int num)
    {
        // 0番目からK個の数列を並び替える
        int[] a = new int[num];
        Array.Copy(input, start, a, 0, num);
        List<int> ret = new List<int>(a);
        ret.Sort();

        return ret;
    }

    private static HashSet<int> getSuccess(int[] input, int K)
    {
        HashSet<int> hs = new HashSet<int>();
        // K個連続した区間が昇順になっているやつを数える
        int suc = 1;
        for (int i = 0; i < input.Length-1; i++)
        {
            if (input[i] < input[i + 1])
            {
                suc++;
                if (suc >= K) hs.Add(i-K+2);
            }
            else
            {
                suc = 1;
            }
        }
        return hs;
    }

    static int getMin(int[] a, int i, int j)
    {
        int ret = a[i];
        for(int k=i+1; k<=j;k++)
        {
            if (a[k] < ret)
                ret = a[k];
        }
        return ret;
    }

    static int getMax(int[] a, int i, int j)
    {
        int ret = a[i];
        for (int k = i + 1; k <= j; k++)
        {
            if (a[k] > ret)
                ret = a[k];
        }
        return ret;
    }

}