Problem:
Score : 700 points

Problem Statement

There are N panels arranged in a row in Takahashi's house, numbered 1 through N. The i-th panel has a number A_i written on it. Takahashi is playing by throwing balls at these panels.

Takahashi threw a ball K times. Let the panel hit by a boll in the i-th throw be panel p_i. He set the score for the i-th throw as i \times A_{p_i}.

He was about to calculate the total score for his throws, when he realized that he forgot the panels hit by balls, p_1,p_2,...,p_K. The only fact he remembers is that for every i (1 ≦ i ≦ K-1), 1 ≦ p_{i+1}-p_i ≦ M holds. Based on this fact, find the maximum possible total score for his throws.

Constraints

1 ≦ M ≦ N ≦ 100,000

1 ≦ K ≦ min(300,N)

1 ≦ A_i ≦ 10^{9}

Partial Scores

In the test set worth 100 points, M = N.

In the test set worth another 200 points, N ≦ 300 and K ≦ 30.

In the test set worth another 300 points, K ≦ 30.

Input

The input is given from Standard Input in the following format:

N M K
A_1 A_2 … A_N

Output

Print the maximum possible total score for Takahashi's throws.

Sample Input 1

5 2 3
10 2 8 10 2

Sample Output 1

56

The total score is maximized when panels 1,3 and 4 are hit, in this order.

Sample Input 2

5 5 2
5 2 10 5 9

Sample Output 2

28

This case satisfies the additional constraint M = N for a partial score.

Sample Input 3

10 3 5
3 7 2 6 9 4 8 5 1 1000000000

Sample Output 3

5000000078

Solution in C++14 (GCC 5.4.1) (judge verdict: Time Limit Exceeded)

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> P;

#define EACH(i,a) for (auto& i : a)
#define FOR(i,a,b) for (ll i=(a);i<(b);i++)
#define RFOR(i,a,b) for (ll i=(b)-1;i>=(a);i--)
#define REP(i,n) for (ll i=0;i<(n);i++)
#define RREP(i,n) for (ll i=(n)-1;i>=0;i--)
#define debug(x) cout<<#x<<": "<<x<<endl
#define pb push_back
#define ALL(a) (a).begin(),(a).end()

const ll linf = 1e18;
const int inf = 1e9;
const double eps = 1e-12;
const double pi = acos(-1);

template<typename T>
istream& operator>>(istream& is, vector<T>& vec) {
    EACH(x,vec) is >> x;
    return is;
}
template<typename T>
ostream& operator<<(ostream& os, vector<T>& vec) {
    REP(i,vec.size()) {
        if (i) os << " ";
        os << vec[i];
    }
    return os;
}
template<typename T>
ostream& operator<<(ostream& os, vector< vector<T> >& vec) {
    REP(i,vec.size()) {
        if (i) os << endl;
        os << vec[i];
    }
    return os;
}

// SegmentTree<int> seg(n, 0x7FFFFFFF, [](int a, int b){return min(a, b);});
template <typename T>
class SegmentTree {
    using func_t = function<T(T, T)>;
    const int n;
    const T id;
    func_t merge;
    vector<T> data;
    T sub(int l, int r, int node, int lb, int ub) {
        if (ub <= l || r <= lb) return id;
        if (l <= lb && ub <= r) return data[node];
        T vl = sub(l, r, node * 2 + 0, lb, (lb + ub) / 2);
        T vr = sub(l, r, node * 2 + 1, (lb + ub) / 2, ub);
        return merge(vl, vr);
    }
    int size(int n) {
            int res;
            for (res = 1; res < n; res <<= 1);
            return res;
    }
public:
    SegmentTree(int n, T id, func_t merge) :
        n(size(n)), id(id), merge(merge), data(size(n) * 2, id) {}
    void update(int p, T val) {
        assert (0 <= p && p < n);
        p += n;
        data[p] = val;
        while (p /= 2) {
            int l = p * 2, r = p * 2 + 1;
            data[p] = merge(data[l], data[r]);
        }
    }
    T find(int l, int r) {
        return sub(l, r, 1, 0, n);
    }
};

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    int n, m, K; cin >> n >> m >> K;
    vector<ll> A(n); cin >> A;
    if (n == m) {
        vector< vector<ll> > dp(2, vector<ll>(n, -linf));
        dp[0] = A;
        REP(i, K-1) {
            ll M = -linf;
            REP(j, n) {
                dp[i+1&1][j] = M+(i+2)*A[j];
                M = max(M, dp[i&1][j]);
            }
        }
        ll ans = 0;
        REP(i, n) ans = max(ans, dp[K-1&1][i]);
        cout << ans << endl;
    }
    else {
        vector<SegmentTree<ll>> dp(2, SegmentTree<ll>(n, -linf, [](ll a, ll b){ return max(a, b); }));
        REP(i, n) {
            dp[0].update(i, A[i]);
        }
        REP(i, K-1) {
            REP(j, n) {
                dp[i+1&1].update(j, dp[i&1].find(max<int>(0, j-m), j)+(i+2)*A[j]);
            }
        }
        ll ans = dp[K-1&1].find(0, n);
        cout << ans << endl;
    }
}