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.IO;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        var N = sc.ReadInt();
        var K = sc.ReadInt();
        var P = sc.ReadIntArray(N);

        var asc = new int[N];
        var a = 0;
        for (int i = 1; i < N; i++)
        {
            if (P[i - 1] > P[i]) a ^= 1;
            asc[i] = a;
        }
        var ascSum = new int[N + 1];
        for (int i = 0; i < N; i++)
        {
            ascSum[i + 1] = ascSum[i] + asc[i];
        }

        var maxSegTree = new SegmentTree(P, true);
        var minSegTree = new SegmentTree(P, false);
        var ans = 0;
        var ascCount = 0;
        for (int l = 0; l < N - K + 1; l++)
        {
            var r = l + K - 1;
            if (l > 0)
            {
                var prevL = l - 1;
                var prevR = r - 1;
                var prevMax = maxSegTree.Find(prevL, prevR + 1);
                var nowMin = minSegTree.Find(l, r + 1);
                // 1つ前のソート結果と一致する場合は数えない
                if (prevMax < P[r] && nowMin > P[l - 1]) continue;
            }
            // 現在の区間がすでにソート済の場合は数えない
            var sum = ascSum[r + 1] - ascSum[l];
            if (sum % K == 0)
            {
                ascCount++;
                continue;
            }
            ans++;
        }
        if (ascCount > 0) ans++;
        Console.WriteLine(ans);
    }

    class SegmentTree
    {
        public int N { get; set; }
        public int[] Node { get; set; }
        public static int INF = int.MaxValue / 2;
        public bool IsMax { get; set; }
        public SegmentTree(int[] a, bool isMax)
        {
            this.IsMax = isMax;
            N = 1;
            while (N < a.Length) N *= 2;
            this.Node = new int[2 * N - 1];
            for (int i = 0; i < this.Node.Length; i++) this.Node[i] = this.IsMax ? -INF : INF;

            for (int i = 0; i < a.Length; i++) this.Node[N + i - 1] = a[i];
            for (int i = N - 2; i >= 0; i--)
            {
                this.Node[i] = this.Compare(this.Node[2 * i + 1], this.Node[2 * i + 2]);
            }
        }
        public void Update(int x, int v)
        {
            x += (this.N - 1);
            this.Node[x] = v;
            while (x > 0)
            {
                x = (x - 1) / 2;
                this.Node[x] = this.Compare(this.Node[2 * x + 1], this.Node[2 * x + 2]);
            }
        }
        public int Find(int leftIndex, int rightIndex)
        {
            return this.Find(leftIndex, rightIndex, 0, 0, this.N);
        }
        private int Find(int a, int b, int k = 0, int l = 0, int r = -1)
        {
            if (r <= a || b <= l) return this.IsMax ? -INF : INF;
            if (a <= l && r <= b) return this.Node[k];
            var vl = this.Find(a, b, 2 * k + 1, l, (l + r) / 2);
            var vr = this.Find(a, b, 2 * k + 2, (l + r) / 2, r);
            return this.Compare(vl, vr);
        }
        private int Compare(int a, int b)
        {
            if (this.IsMax) return Math.Max(a, b);
            else return Math.Min(a, b);
        }
    }

    static Scanner sc = new Scanner();
}

class Scanner
{
    string[] S = new string[0];
    int Index = 0;
    char[] Separators = new char[] { ' ' };

    public string Next()
    {
        if (this.Index < this.S.Length) return this.S[this.Index++];
        var line = "";
        while (line == "") line = Console.ReadLine();
        this.S = line.Split(this.Separators, StringSplitOptions.RemoveEmptyEntries);
        if (this.S.Length == 0) return this.Next();
        this.Index = 0;
        return this.S[this.Index++];
    }
    public string ReadStr()
    {
        return this.Next();
    }
    public char ReadChar()
    {
        return this.Next()[0];
    }
    public int ReadInt()
    {
        return int.Parse(this.Next());
    }
    public uint ReadUInt()
    {
        return uint.Parse(this.Next());
    }
    public long ReadLong()
    {
        return long.Parse(this.Next());
    }
    public double ReadDouble()
    {
        return double.Parse(this.Next());
    }
    public Tuple<int, int> ReadTup(int add = 0)
    {
        return Tuple.Create(this.ReadInt() + add, this.ReadInt() + add);
    }
    public Tuple<long, long> ReadTupLong(int add = 0)
    {
        return Tuple.Create(this.ReadLong() + add, this.ReadLong() + add);
    }
    public Tuple<int, int, int> ReadTup3(int add = 0)
    {
        return Tuple.Create(this.ReadInt() + add, this.ReadInt() + add, this.ReadInt() + add);
    }
    public Tuple<int, int, int, int> ReadTup4(int add = 0)
    {
        return Tuple.Create(this.ReadInt() + add, this.ReadInt() + add, this.ReadInt() + add, this.ReadInt() + add);
    }
    public int[] ReadIntArray(int n)
    {
        var array = new int[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadInt();
        }
        return array;
    }
    public long[] ReadLongArray(int n)
    {
        var array = new long[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadLong();
        }
        return array;
    }
    public double[] ReadDoubleArray(int n)
    {
        var array = new double[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadDouble();
        }
        return array;
    }
    public char[] ReadCharArray(int n)
    {
        var array = new char[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadChar();
        }
        return array;
    }
    public string[] ReadStrArray(int n)
    {
        var array = new string[n];
        for (int i = 0; i < array.Length; i++)
        {
            array[i] = this.ReadStr();
        }
        return array;
    }
    public Tuple<long, long>[] ReadTupLongArray(int n, int add = 0)
    {
        var array = new Tuple<long, long>[n];
        for (int i = 0; i < n; i++)
        {
            array[i] = this.ReadTupLong(add);
        }
        return array;
    }
    public Tuple<int, int>[] ReadTupArray(int n, int add = 0)
    {
        var array = new Tuple<int, int>[n];
        for (int i = 0; i < n; i++)
        {
            array[i] = this.ReadTup(add);
        }
        return array;
    }
    public Tuple<int, int, int>[] ReadTup3Array(int n, int add = 0)
    {
        var array = new Tuple<int, int, int>[n];
        for (int i = 0; i < n; i++)
        {
            array[i] = this.ReadTup3(add);
        }
        return array;
    }
    public Tuple<int, int, int, int>[] ReadTup4Array(int n, int add = 0)
    {
        var array = new Tuple<int, int, int, int>[n];
        for (int i = 0; i < n; i++)
        {
            array[i] = this.ReadTup4(add);
        }
        return array;
    }
}