#include <iostream>
#include <algorithm>
#include <utility>
#include <vector>
#include <numeric>
#include <tuple>
#include <stack>

template <class T, class U>
inline bool chmin(T& lhs, const U& rhs) {
  if (lhs > rhs) {
    lhs = rhs;
    return true;
  }
  return false;
}

template <class T, class U>
inline bool chmax(T& lhs, const U& rhs) {
  if (lhs < rhs) {
    lhs = rhs;
    return true;
  }
  return false;
}

// [l, r) from l to r
struct range {
  struct itr {
    int i;
    constexpr itr(int i_): i(i_) { }
    constexpr void operator ++ () { ++i; }
    constexpr int operator * () const { return i; }
    constexpr bool operator != (itr x) const { return i != x.i; }
  };
  const itr l, r;
  constexpr range(int l_, int r_): l(l_), r(std::max(l_, r_)) { }
  constexpr itr begin() const { return l; }
  constexpr itr end() const { return r; }
};

// [l, r) from r to l
struct revrange {
  struct itr {
    int i;
    constexpr itr(int i_): i(i_) { }
    constexpr void operator ++ () { --i; }
    constexpr int operator * () const { return i; }
    constexpr bool operator != (itr x) const { return i != x.i; }
  };
  const itr r, l;
  constexpr revrange(int l_, int r_): l(l_ - 1), r(std::max(l_, r_) - 1) { }
  constexpr itr begin() const { return r; }
  constexpr itr end() const { return l; }
};

template <class T>
class sliding_window_aggregation {
public:
  using value_type = typename T::value_type;
  using value_operation = typename T::value_operation;

private:
  struct node {
    value_type value, sum;
    node (const value_type &value_, const value_type &sum_): value(value_), sum(sum_) { }
  };
  const value_operation op;
  std::stack<node> front, back;

public:
  sliding_window_aggregation(): op(value_operation()), front(), back() { }

  value_type fold() const {
    if (front.empty()) {
      return back.top().sum;
    } 
    else if (back.empty()) {
      return front.top().sum;
    } 
    else {
      return op(front.top().sum, back.top().sum);
    }
  }

  int size() const {
    return front.size() + back.size();
  }

  void push(const value_type &x) {
    if (back.empty()) {
      back.emplace(x, x);
    } 
    else {
      value_type tmp = op(back.top().sum, x);
      back.emplace(x, tmp);
    }
  }

  void pop() {
    if (front.empty()) {
      front.emplace(back.top().value, back.top().value);
      back.pop();
      while (!back.empty()) {
        value_type tmp = op(back.top().value, front.top().sum);
        front.emplace(back.top().value, tmp);
        back.pop();
      }
    }
    front.pop();
  }

};

template <class T>
struct range_max {
  using value_type = T;
  struct value_operation {
    value_type operator () (const value_type &x, const value_type &y) const {
      return x > y ? x : y;
    }
  };
};

int main() {
  int N, M, K;
  std::cin >> N >> M >> K;
  std::vector<long long> A(N);
  for (long long &x: A) {
    std::cin >> x;
  }
  auto dp = A;
  for (int k: range(1, K)) {
    sliding_window_aggregation<range_max<long long>> swag;
    for (int i: range(0, k)) {
      swag.push(dp[i]);
      while (swag.size() > M) {
        swag.pop();
      }
      dp[i] = 0;
    }
    for (int i: range(k, N)) {
      long long tmp = dp[i];
      dp[i] = swag.fold() + A[i] * (k + 1);
      swag.push(tmp);
      while (swag.size() > M) {
        swag.pop();
      }
    }
  }
  std::cout << *std::max_element(dp.begin(), dp.end()) << '\n';
  return 0;
}


Measured memory_bytes: 3572