Problem:
Score : 500 points

Problem Statement

Given are a sequence of N positive integers A_1, A_2, \ldots, A_N, and a positive integer K.

Find the number of non-empty contiguous subsequences in A such that the remainder when dividing the sum of its elements by K is equal to the number of its elements. We consider two subsequences different if they are taken from different positions, even if they are equal sequences.

Constraints

All values in input are integers.

1 \leq N \leq 2\times 10^5

1 \leq K \leq 10^9

1 \leq A_i \leq 10^9

Input

Input is given from Standard Input in the following format:

N K
A_1 A_2 \cdots A_N

Output

Print the number of subsequences that satisfy the condition.

Sample Input 1

5 4
1 4 2 3 5

Sample Output 1

4

Four sequences satisfy the condition: (1), (4,2), (1,4,2), and (5).

Sample Input 2

8 4
4 2 4 2 4 2 4 2

Sample Output 2

7

(4,2) is counted four times, and (2,4) is counted three times.

Sample Input 3

10 7
14 15 92 65 35 89 79 32 38 46

Sample Output 3

8

Solution in C# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Linq;
using System.Numerics;
using System.Collections.Generic;
using System.IO;
using System.Text;
using N = System.Int32;

public class Solver
{
    public void Solve()
    {
        N n = ri;
        N k = ri;
        List<N> a = new List<N>();
        N[] sum = new N[n + 1];
        for(int i = 0; i < n; i++)
        {
            a.Add(ri % k);
            sum[i + 1] = (sum[i] + a[i]) % k;
        }
        N p = 0;
        for(N len = 1; len <= n && len<k; len++)
        {
            for(N start = 0; start + len <= n; start++)
            {
                if ((sum[start + len] - sum[start] + k) % k == len) { p++; }
            }
        }
        Write(p);
    }
    

    int ri { get { return sc.Integer(); } }
    long rl { get { return sc.Long(); } }
    double rd { get { return sc.Double(); } }
    string rs { get { return sc.Scan(); } }
    public StreamScanner sc = new StreamScanner(Console.OpenStandardInput());
    public Algorithm alg = new Algorithm();

    private const N mod = 1000000007;
    N Reverse(N n) { return Pow(n, mod - 2); }
    N Mul(params N[] n) { N p = n[0]; for (N i = 1; i < n.Length; i++) { p = (p * n[i]) % mod; } return p; }
    N Pow(N n, N p) { N t = n, q = 1; while (p > 0) { if (p % 2 == 1) { q = (q * t) % mod; } t = (t * t) % mod; p >>= 1; } return q; }
    N PowUpper(N n, N b) { N p = 1; while (p <= n) { p *= b; } return p; }
    N Sign(N n) { return n == 0 ? 0 : n > 0 ? 1 : -1; }
    N Abs(N n) { return (n > 0) ? n : -n; }
    N Gcd(params N[] n) { N p = n[0]; for (N i = 1; i < n.Length; i++) { p = Gcd(p, n[i]); } return p; }
    N Gcd(N a, N b) { return (a == 0) ? b : Gcd(b % a, a); }
    N Lcm(params N[] n) { N p = n[0]; for (N i = 1; i < n.Length; i++) { p = Lcm(p, n[i]); } return p; }
    N Lcm(N a, N b) { return (a / Gcd(a, b) * b) % mod; }
    void Write<T>(T t) { Console.WriteLine(t.ToString()); }
    void YN(bool t) { Console.WriteLine(t ? "YES" : "NO"); }
    void Yn(bool t) { Console.WriteLine(t ? "Yes" : "No"); }
    void yn(bool t) { Console.WriteLine(t ? "yes" : "no"); }
}

static class Program
{
    static public void Main(string[] args)
    {
        Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
        var solver = new Solver();
        solver.Solve();
        Console.Out.Flush();
    }
}

public class Algorithm
{
    public int[] ZAlgorithm(string s)
    {
        int[] p = new int[s.Length];
        p[0] = s.Length;
        int i = 1, j = 0;
        while (i < s.Length)
        {
            while (i + j < s.Length && s[j] == s[i + j]) ++j;
            p[i] = j;
            if (j == 0) { ++i; continue; }
            int k = 1;
            while (i + k < s.Length && k + p[k] < j)
            {
                p[i + k] = p[k];
                ++k;
            }
            i += k; j -= k;
        }
        return p;
    }

    public List<int> SieveOfEratosthenes(int n)
    {
        List<int> l = new List<int>();
        if (n >= 2) { l.Add(2); }
        bool[] t = new bool[(n - 1) / 2];
        for (int p = 3; p <= n; p += 2) { if (!t[(p - 3) / 2]) { l.Add(p); for (int q = p * p; q <= n; q += p) { t[(q - 3) / 2] = true; } } }
        return l;
    }

    public Dictionary<int,int> PrimeFactor(int n, List<int> primetable)
    {
        Dictionary<int, int> d = new Dictionary<int, int>();
        int t = 0;
        foreach(int i in primetable)
        {
            if (n % i == 0)
            {
                while (n % 2 == 0) { n /= i; t++; }
                d.Add(i, t);
            }
        }
        if (n > 1) { d.Add(n, 1); }
        return d;
    }
}

public class PriorityQueue<T> where T : IComparable
{
    private IComparer<T> _comparer = null;
    private int _type = 0;

    private T[] _heap;
    private int _sz = 0;

    private int _count = 0;

    /// <summary>
    /// Priority Queue with custom comparer
    /// </summary>
    public PriorityQueue(IComparer<T> comparer)
    {
        _heap = new T[128];
        _comparer = comparer;
    }

    /// <summary>
    /// Priority queue
    /// </summary>
    /// <param name="type">0: asc, 1:desc</param>
    public PriorityQueue(int type = 0)
    {
        _heap = new T[128];
        _type = type;
    }

    private int Compare(T x, T y)
    {
        if (_comparer != null) return _comparer.Compare(x, y);
        return _type == 0 ? x.CompareTo(y) : y.CompareTo(x);
    }

    public void Push(T x)
    {
        _count++;
        if (_count > _heap.Length)
        {
            var newheap = new T[_heap.Length * 2];
            for (int n = 0; n < _heap.Length; n++) newheap[n] = _heap[n];
            _heap = newheap;
        }

        //node number
        var i = _sz++;

        while (i > 0)
        {
            //parent node number
            var p = (i - 1) / 2;

            if (Compare(_heap[p], x) <= 0) break;

            _heap[i] = _heap[p];
            i = p;
        }

        _heap[i] = x;
    }

    public T Pop()
    {
        _count--;

        T ret = _heap[0];
        T x = _heap[--_sz];

        int i = 0;
        while (i * 2 + 1 < _sz)
        {
            //children
            int a = i * 2 + 1;
            int b = i * 2 + 2;

            if (b < _sz && Compare(_heap[b], _heap[a]) < 0) a = b;

            if (Compare(_heap[a], x) >= 0) break;

            _heap[i] = _heap[a];
            i = a;
        }

        _heap[i] = x;

        return ret;
    }

    public int Count()
    {
        return _count;
    }

    public T Peek()
    {
        return _heap[0];
    }

    public bool Contains(T x)
    {
        for (int i = 0; i < _sz; i++) if (x.Equals(_heap[i])) return true;
        return false;
    }

    public void Clear()
    {
        while (this.Count() > 0) this.Pop();
    }

    public IEnumerator<T> GetEnumerator()
    {
        var ret = new List<T>();

        while (this.Count() > 0)
        {
            ret.Add(this.Pop());
        }

        foreach (var r in ret)
        {
            this.Push(r);
            yield return r;
        }
    }

    public T[] ToArray()
    {
        T[] array = new T[_sz];
        int i = 0;

        foreach (var r in this)
        {
            array[i++] = r;
        }

        return array;
    }
}

public class StreamScanner
{
    public StreamScanner(Stream stream) { str = stream; }
    private readonly Stream str;
    private readonly byte[] buf = new byte[1024];
    private int len, ptr;
    public bool isEof = false;
    public bool IsEndOfStream { get { return isEof; } }
    private byte read()
    {
        if (isEof) throw new EndOfStreamException();
        if (ptr >= len)
        {
            ptr = 0;
            if ((len = str.Read(buf, 0, 1024)) <= 0)
            {
                isEof = true;
                return 0;
            }
        }
        return buf[ptr++];
    }
    public char Char()
    {
        byte b = 0;
        do b = read();
        while (b < 33 || 126 < b);
        return (char)b;
    }
    public string Scan()
    {
        var sb = new StringBuilder();
        for (var b = Char(); b >= 33 && b <= 126; b = (char)read())
            sb.Append(b);
        return sb.ToString();
    }
    public long Long()
    {
        long ret = 0; byte b = 0; var ng = false;
        do b = read();
        while (b != '-' && (b < '0' || '9' < b));
        if (b == '-') { ng = true; b = read(); }
        for (; true; b = read())
        {
            if (b < '0' || '9' < b)
                return ng ? -ret : ret;
            else ret = ret * 10 + b - '0';
        }
    }
    public int Integer() { return (int)Long(); }
    public double Double() { return double.Parse(Scan()); }
}