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: Accepted)

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

class SegTree<T>
{
    private readonly T[] Array;
    private readonly Comparison<T> Compare;
    private readonly int N;
    private readonly T Max;

    public SegTree(int size, T max) : this(size, Comparer<T>.Default, max)
    {
    }

    public SegTree(int size, IComparer<T> comparer, T max) : this(size, comparer.Compare, max)
    {
    }

    public SegTree(int size, Comparison<T> comparison, T max)
    {
        Max = max;
        N = 1;
        while (N < size)
        {
            N *= 2;
        }

        Compare = comparison;
        Array = new T[2 * N];
        for (int i = 1; i < 2 * N; i++)
        {
            Array[i] = max;
        }
    }

    new public T this[int i]
    {
        get { return Array[i + N]; }
        set { Update(value, i); }
    }


    private T Min(T x, T y)
    {
        return Compare(x, y) < 0 ? x : y;
    }

    public void Update(T item, int index)
    {
        index += N;
        Array[index] = item;
        while (index > 1)
        {
            index /= 2;
            Array[index] = Min(Array[index * 2], Array[index * 2 + 1]);
        }
    }

    private T Q(int left, int right, int k, int l, int r)
    {
        if (left <= l && r <= right)
        {
            return Array[k];
        }

        if (r <= left || right <= l)
        {
            return Max;
        }

        return Min(Q(left, right, k * 2, l, (l + r) / 2), Q(left, right, k * 2 + 1, (l + r) / 2, r));
    }

    public T Query(int left, int right)
    {
        return Q(left, right, 1, 0, N);
    }
}

namespace Algorithm
{
    using N = Int32;

    class RSQ
    {
        private readonly N[] Array;
        private readonly int len;

        public RSQ(int size)
        {
            len = 1;
            while (len < size)
            {
                len *= 2;
            }

            Array = new N[len * 2];
        }

        public void Update(N item, int index)
        {
            index += len;
            Array[index] = item;
            while (index > 1)
            {
                index /= 2;
                Array[index] = Array[index * 2] + Array[index * 2 + 1];
            }
        }

        private N Q(int left, int right, int k, int l, int r)
        {
            if (left <= l && r <= right)
            {
                return Array[k];
            }

            if (r <= left || right <= l)
            {
                return 0;
            }

            return Q(left, right, k * 2, l, (l + r) / 2) + Q(left, right, k * 2 + 1, (l + r) / 2, r);
        }

        public N Query(int left, int right)
        {
            return Q(left, right, 1, 0, len);
        }

        public N this[int i]
        {
            get { return Array[i + len]; }
            set { Update(value, i); }
        }
    }
}

public class Program
{
    private int N, K;
    private int[] P;

    public void Solve()
    {
        var sc = new Scanner();
        N = sc.NextInt();
        K = sc.NextInt();
        P = sc.IntArray();

        var min = new SegTree<int>(N, int.MaxValue);
        var max = new SegTree<int>(N, (a, b) => -a.CompareTo(b), int.MinValue);
        int ans = N - K + 1;
        // Pの中に長さKのソート済みぶぶんれつ

        var cntA = Count(K);
        int cc = cntA.Count(i => i == 1);
        if (cc != 0)
        {
            ans -= cc - 1;
        }
        
    

        for (int i = 0; i < N; i++)
        {
            min[i] = P[i];
            max[i] = P[i];
        }
        //.WriteLine(ans);
        for (int i = 0; i < N - K; i++)
        {
            // iのソートとi+1のソートが一致するか
            // P[i]が [i, i+K)で最小
            bool a = P[i] == min.Query(i, i + K);
            bool b = P[i + K] == max.Query(i + 1, i + K + 1);
            bool c = cntA[i] == 0;
            if (a && b && c)
                ans--;
        }

        // 


        Console.WriteLine(ans);
    }

    private int[] Count(int k)
    {
        var cnt = new int[N];
        bool f = false;

        for (int i = 0; i <= N - k;)
        {
            int j;
            bool flag = true;
            if (f)
            {
                j = i + k - 1;

                if (P[j - 1] > P[j])
                {
                    flag = false;
                }
            }
            else
            {
                // 前がソート済みじゃない

                for (j = i + 1; j < i + k; j++)
                {
                    if (P[j - 1] > P[j])
                    {
                        flag = false;
                        break;
                    }
                }
            }

            if (flag)
            {
                cnt[i] = 1;
                i++;
                f = true;
            }
            else
            {
                i = j;
                f = false;
            }
        }

        return cnt;
    }

    public static void Main(string[] args)
    {
        new Program().Solve();
    }
}

class Scanner
{
    public Scanner()
    {
        _pos = 0;
        _line = new string[0];
    }

    const char Separator = ' ';
    private int _pos;
    private string[] _line;

    #region スペース区切りで取得

    public string Next()
    {
        if (_pos >= _line.Length)
        {
            _line = Console.ReadLine().Split(Separator);
            _pos = 0;
        }

        return _line[_pos++];
    }

    public int NextInt()
    {
        return int.Parse(Next());
    }

    public long NextLong()
    {
        return long.Parse(Next());
    }

    public double NextDouble()
    {
        return double.Parse(Next());
    }

    #endregion

    #region 型変換

    private int[] ToIntArray(string[] array)
    {
        var result = new int[array.Length];
        for (int i = 0; i < array.Length; i++)
        {
            result[i] = int.Parse(array[i]);
        }

        return result;
    }

    private long[] ToLongArray(string[] array)
    {
        var result = new long[array.Length];
        for (int i = 0; i < array.Length; i++)
        {
            result[i] = long.Parse(array[i]);
        }

        return result;
    }

    private double[] ToDoubleArray(string[] array)
    {
        var result = new double[array.Length];
        for (int i = 0; i < array.Length; i++)
        {
            result[i] = double.Parse(array[i]);
        }

        return result;
    }

    #endregion

    #region 配列取得

    public string[] Array()
    {
        if (_pos >= _line.Length)
            _line = Console.ReadLine().Split(Separator);

        _pos = _line.Length;
        return _line;
    }

    public int[] IntArray()
    {
        return ToIntArray(Array());
    }

    public long[] LongArray()
    {
        return ToLongArray(Array());
    }

    public double[] DoubleArray()
    {
        return ToDoubleArray(Array());
    }

    #endregion
}