Problem:
Problem
長さ $N$ の数列 $A = \{ a_0, a_1, \ldots, a_{N-1} \}$ が与えられる。
  この数列をいくつかの「長さ $L$ 以上の連続する部分列」に分割することを考える。
より形式的には、以下の $3$ つの条件を全て満たすような整数列 $D = \{ d_0, d_1, \ldots, d_M \} $ を考える。
$d_0 = 0$
$d_M = N$
$L \leq d_{i+1}-d_i \ (0 \leq i \lt M)$
$f(D) = \displaystyle \sum_{i = 0}^{M - 1} \max_{d_i \leq j \lt d_{i+1}} a_j $ とする。
  $f(D)$ の最大値を求めよ。
Input
入力は以下の形式で与えられる。
$N$ $L$
$a_0$ $a_1$ $\ldots$ $a_{N-1}$
Constraints
入力は以下の条件を満たす。
$1 \leq L \leq N \leq 2 \times 10^5$
$-10^9 \leq a_i \leq 10^9$
入力は全て整数である
Output
$f(D)$ の最大値を一行に出力する。
Sample Input 1
3 1
1 2 3
Sample Output 1
6
$D = \{0,1,2,3\}$ とすると、$f(D) = 1+2+3 = 6$ となり、これが最大です。
Sample Input 2
3 2
1 2 3
Sample Output 2
3
$D$ として考えられるものは $\{0, 3\}$ のみです。
Sample Input 3
6 2
1 1 5 5 1 1
Sample Output 3
10
Sample Input 4
5 1
-1 -10 -1 -10 -1
Sample Output 4
-1

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
#if __has_include(<atcoder/all>)
#include <atcoder/all>
#endif
using ll=long long;
using ull=unsigned long long;
using P=pair<ll,ll>;
template<typename T>using minque=priority_queue<T,vector<T>,greater<T>>;
template<typename T>bool chmax(T &a,const T &b){return (a<b?(a=b,true):false);}
template<typename T>bool chmin(T &a,const T &b){return (a>b?(a=b,true):false);}
template<typename T1,typename T2>istream &operator>>(istream &is,pair<T1,T2>&p){is>>p.first>>p.second;return is;}
template<typename T>istream &operator>>(istream &is,vector<T> &a){for(auto &i:a)is>>i;return is;}
template<typename T1,typename T2>void operator++(pair<T1,T2>&a,int n){a.first++,a.second++;}
template<typename T1,typename T2>void operator--(pair<T1,T2>&a,int n){a.first--,a.second--;}
template<typename T>void operator++(vector<T>&a,int n){for(auto &i:a)i++;}
template<typename T>void operator--(vector<T>&a,int n){for(auto &i:a)i--;}
#define overload3(_1,_2,_3,name,...) name
#define rep1(i,n) for(int i=0;i<(int)(n);i++)
#define rep2(i,l,r) for(int i=(int)(l);i<(int)(r);i++)
#define rep(...) overload3(__VA_ARGS__,rep2,rep1)(__VA_ARGS__)
#define reps(i,l,r) rep2(i,l,r)
#define all(x) x.begin(),x.end()
#define pcnt(x) __builtin_popcountll(x)
#define fin(x) return cout<<(x)<<'\n',static_cast<void>(0)
#define yn(x) cout<<((x)?"Yes\n":"No\n")
ll myceil(ll a,ll b){return (a+b-1)/b;}
template<typename T,size_t n,size_t id=0>
auto vec(const int (&d)[n],const T &init=T()){
  if constexpr (id<n)return vector(d[id],vec<T,n,id+1>(d,init));
  else return init;
}
#ifdef LOCAL
#include<debug.h>
#else
#define debug(...) static_cast<void>(0)
#define debugg(...) static_cast<void>(0)
template<typename T1,typename T2>ostream &operator<<(ostream &os,const pair<T1,T2>&p){os<<p.first<<' '<<p.second;return os;}
#endif
struct Timer{
  clock_t start;
  Timer(){
    start=clock();
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout<<fixed<<setprecision(16);
  }
  inline double now(){return (double)(clock()-start)/1000;}
  #ifdef LOCAL
  ~Timer(){
    cerr<<"time:";
    cerr<<now();
    cerr<<"ms\n";
  }
  #endif
}timer;
void SOLVE();
int main(){
  int testcase=1;
  //cin>>testcase;
  for(int i=0;i<testcase;i++){
    SOLVE();
  }
}
template<typename T>
struct fast_stack{
private:
  T *st;
  int p;
public:
  fast_stack(int n):p(0){
    st=new T[n];
  }
  fast_stack(){}
  inline void push(const T&x){st[p++]=x;}
  template<typename...Args>
  inline T& emplace(Args&&...args){
    st[p++]=T(std::forward<Args>(args)...);
    return st[p-1];
  }
  inline T& pop(){return st[--p];}
  inline T top()const{return st[p-1];}
  inline T& top(){return st[p-1];}
  inline int size()const{return p;}
  inline bool empty()const{return !p;}
  inline void clear(){p=0;}
  inline void kill(){delete[] st;}
};
#include<type_traits>
template<typename T>
constexpr std::enable_if_t<std::numeric_limits<T>::digits<=32,int>msb(T n){return n==0?-1:31-__builtin_clz(n);}
template<typename T>
constexpr std::enable_if_t<(std::numeric_limits<T>::digits>32),int>msb(T n){return n==0?-1:63-__builtin_clzll(n);}

template<typename T>
constexpr std::enable_if_t<std::numeric_limits<T>::digits<=32,int>lsb(T n){return n==0?-1:__builtin_ctz(n);}
template<typename T>
constexpr std::enable_if_t<(std::numeric_limits<T>::digits>32),int>lsb(T n){return n==0?-1:__builtin_ctzll(n);}

template<typename T>
constexpr std::enable_if_t<std::is_integral_v<T>,T>floor_pow2(T n){return n==0?0:T(1)<<msb(n);}

template<typename T>
constexpr std::enable_if_t<std::is_integral_v<T>,T>ceil_pow2(T n){return n<=1?1:T(1)<<(msb(n-1)+1);}
template<typename Func>
std::vector<decltype(std::declval<Func>()(0,0))>monge_shortest_path(int n,const Func&f){
  using T=decltype(f(0,0));
  static constexpr T inf=std::numeric_limits<T>::max();
  std::vector<T>dp(n,inf);
  std::vector<int>amin(n);
  dp[0]=0;
  dp[n-1]=f(0,n-1);
  fast_stack<std::pair<int,int>>st(msb(n)*3+1);
  st.emplace(0,n-1);
  while(!st.empty()){
    auto [l,r]=st.pop();
    if(l<0){
      l=~l,r=~r;
      int mid=(l+r)/2;
      for(int i=l+1;i<=mid;i++){
        T now=dp[i]+f(i,r);
        if(dp[r]>now){
          dp[r]=now;
          amin[r]=i;
        }
      }
    }
    else if(l+1<r){
      int mid=(l+r)/2;
      st.emplace(mid,r);
      st.emplace(~l,~r);
      st.emplace(l,mid);
      for(int i=amin[l];i<=amin[r];i++){
        T now=dp[i]+f(i,mid);
        if(dp[mid]>now){
          dp[mid]=now;
          amin[mid]=i;
        }
      }
    }
  }
  st.kill();
  return dp;
}
template<typename M,int L=5>
struct SparseTable{
  using S=typename M::S;
private:
  std::vector<S>dat,prefix,suffix;
  std::vector<std::vector<S>>sp;
public:
  SparseTable(){}
  SparseTable(std::vector<S>a):dat(a){
    int n=a.size();
    n=(n+(1<<L)-1)&~((1<<L)-1);
    a.resize(n,M::e());
    prefix=suffix=a;
    std::vector<S>d2(n>>L,M::e());
    for(int i=0;i<d2.size();i++){
      for(int j=0;j<(1<<L);j++)d2[i]=M::op(d2[i],a[(i<<L)+j]);
    }
    for(int i=0;i<(n>>L);i++){
      for(int j=1;j<(1<<L);j++)prefix[(i<<L)+j]=M::op(prefix[(i<<L)+j-1],prefix[(i<<L)+j]);
    }
    for(int i=(n>>L)-1;i>=0;i--){
      for(int j=(1<<L)-1;j>=1;j--)suffix[(i<<L)+j-1]=M::op(suffix[(i<<L)+j-1],suffix[(i<<L)+j]);
    }
    int d=(d2.size()==1?1:32-__builtin_clz(d2.size()-1));
    sp.resize(d,d2);
    for(int i=1;i<d;i++){
      int w=1<<i;
      for(int j=w;j<=d2.size();j+=w*2){
        for(int k=j-2;k>=j-w;k--)sp[i][k]=M::op(d2[k],sp[i][k+1]);
        int r=std::min<int>(d2.size(),j+w);
        for(int k=j+1;k<r;k++)sp[i][k]=M::op(sp[i][k-1],d2[k]);
      }
    }
  }
  S prod(int l,int r)const{
    if(l==r)return M::e();
    r--;
    int lid=l>>L,rid=r>>L;
    if(lid==rid){
      S ret=M::e();
      for(int i=l;i<=r;i++)ret=M::op(ret,dat[i]);
      return ret;
    }
    else{
      lid++;
      rid--;
      S mid=M::e();
      if(lid==rid)mid=sp[0][lid];
      else if(lid<rid){
        int s=msb(lid^rid);
        mid=M::op(sp[s][lid],sp[s][rid]);
      }
      return M::op(suffix[l],M::op(mid,prefix[r]));
    }
  }
};
template<typename T>
struct MonoidMax{
  using S=T;
  using F=std::nullptr_t;
  static inline S op(const S&x,const S&y){return x<y?y:x;}
  static inline S e(){return std::numeric_limits<S>::min();}
  static inline S mapping(F,const S&x,long long){return x;}
  static inline F composition(F,F){return nullptr;}
  static inline F id(){return nullptr;}
  static inline void revS(S&x){}
  static inline S pow(const S&x,long long p){return x;}
};
void SOLVE(){
  int n,l;
  cin>>n>>l;
  vector<ll>a(n);
  cin>>a;
  SparseTable<MonoidMax<ll>>sp(a);
  cout<<-monge_shortest_path(n+1,[&](int i,int j)->ll {
    if(j-i<l)return 1e18;
    return -sp.prod(i,j);
  })[n]<<endl;
}
accuracy: 1
time_ms: 20
memory_kb: 10852
final_rank: 5

code_snippet: // AOJ #3086
// Partition 2025.2.6

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll MINF = -1e18;

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {  // 整数の入力
	int n = 0, c = gc();
	if (c == '-') {	c = gc();
		do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
		return -n;
	}
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(ll n) { // 整数の表示（出力）
	char b[30];
	if (!n) pc('0');
	else {
		if (n < 0) pc('-'), n = -n;
		int i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

struct SegTree {
    int n;
    vector<ll> tree;
    SegTree(int n) : n(n) {
        tree.assign(4*n, MINF);
    }
    void update(int idx, int l, int r, int pos, ll val) {
        if(l == r){
            tree[idx] = val;
            return;
        }
        int mid = (l + r) / 2;
        if(pos <= mid)
            update(idx*2, l, mid, pos, val);
        else
            update(idx*2+1, mid+1, r, pos, val);
        tree[idx] = max(tree[idx*2], tree[idx*2+1]);
    }
    ll query(int idx, int l, int r, int ql, int qr) {
        if(ql > r || qr < l)
            return MINF;
        if(ql <= l && r <= qr)
            return tree[idx];
        int mid = (l + r) / 2;
        return max(query(idx*2, l, mid, ql, qr), query(idx*2+1, mid+1, r, ql, qr));
    }
    void updatePos(int pos, ll val) {
        update(1, 0, n-1, pos, val);
    }
    ll queryRange(int l, int r) {
        if(l > r) return MINF;
        return query(1, 0, n-1, l, r);
    }
};
 
int main(){
    int N = Cin(), L = Cin();
    vector<ll> A(N);
    for (int i = 0; i < N; i++) A[i] = Cin();
 
    vector<ll> dp(N+1, MINF);
    dp[0] = 0;
 
    int sizeTree = N+1;
    SegTree seg_dp(sizeTree), seg_dpa(sizeTree);
    seg_dp.updatePos(0, dp[0]);
    if(N > 0) seg_dpa.updatePos(0, dp[0] + A[0]);
    for (int j = 1; j < sizeTree; j++){
        seg_dp.updatePos(j, MINF);
        seg_dpa.updatePos(j, MINF);
    }
 
    vector<int> B;
    for (int i = 1; i <= N; i++){
        int newIdx = i - 1;
        while(!B.empty() && A[newIdx] >= A[B.back()])
            B.pop_back();
        B.push_back(newIdx);
 
        int X = i - L;
        if(X < 0) continue;
 
        ll best = MINF;
        if((int)B.size() == i){
            best = seg_dpa.queryRange(0, X);
        } else {
            int prev = 0;
            int segStart = 0, segEnd = min(X, B[0]);
            if(segStart <= segEnd){
                ll candidate = seg_dp.queryRange(segStart, segEnd) + A[B[0]];
                best = max(best, candidate);
            }
            for (int r = 0; r < (int)B.size()-1; r++){
                segStart = B[r] + 1;
                segEnd = min(X, B[r+1]);
                if(segStart <= segEnd){
                    ll candidate = seg_dp.queryRange(segStart, segEnd) + A[B[r+1]];
                    best = max(best, candidate);
                }
            }
            if(!B.empty() && X > B.back()){
                segStart = B.back() + 1;
                segEnd = X;
                ll candidate = seg_dpa.queryRange(segStart, segEnd);
                best = max(best, candidate);
            }
        }
        dp[i] = best;
        seg_dp.updatePos(i, dp[i]);
        if(i < N) seg_dpa.updatePos(i, dp[i] + A[i]);
    }
    Cout(dp[N]);
    return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 15132
final_rank: 15

code_snippet: #include "bits/stdc++.h"
 
using namespace std;
 
template <typename T1, typename T2> istream &operator>>(istream &is, pair<T1, T2> &pa) { is >> pa.first >> pa.second; return is; }
template <typename T> istream &operator>>(istream &is, vector<T> &vec) { for (auto &v : vec) is >> v; return is; }
template <typename T1, typename T2> ostream &operator<<(ostream &os, const pair<T1, T2> &pa) { os << "(" << pa.first << "," << pa.second << ")"; return os; }
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) { os << "["; for (auto v : vec) os << v << ","; os << "]"; return os; }
template <typename T> ostream &operator<<(ostream &os, const deque<T> &vec) { os << "deq["; for (auto v : vec) os << v << ","; os << "]"; return os; }
template <typename T> ostream &operator<<(ostream &os, const set<T> &vec) { os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template <typename T> ostream &operator<<(ostream &os, const multiset<T> &vec) { os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template <typename T> ostream &operator<<(ostream &os, const unordered_set<T> &vec) { os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template <typename T> ostream &operator<<(ostream &os, const unordered_multiset<T> &vec) { os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template <typename TK, typename TV> ostream &operator<<(ostream &os, const unordered_map<TK, TV> &mp) { os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }
template <typename TK, typename TV> ostream &operator<<(ostream &os, const map<TK, TV> &mp) { os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }
template <typename T> void resize_array(vector<T> &vec, int len) { vec.resize(len); }
template <typename T, typename... Args> void resize_array(vector<T> &vec, int len, Args... args) { vec.resize(len); for (auto &v : vec) resize_array(v, args...); }
template <typename T1, typename T2> pair<T1, T2> operator+(const pair<T1, T2> &l, const pair<T1, T2> &r) { return make_pair(l.first + r.first, l.second + r.second); }
template <typename T1, typename T2> pair<T1, T2> operator-(const pair<T1, T2> &l, const pair<T1, T2> &r) { return make_pair(l.first - r.first, l.second - r.second); }
long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }
mt19937 mrand(random_device{}());
int rnd(int x) { return mrand() % x; }

// 函数名后面加 ll 就可以计算 long long类型对应的结果
// __builtin_ffs(x)
// 返回x中最后一个为1的位是从后向前的第几位
// __builtin_popcount(x)
// x中1的个数
// __builtin_ctz(x)
// x末尾0的个数。x=0时结果未定义。
// __builtin_clz(x)
// x前导0的个数。x=0时结果未定义。
// __builtin_parity(x)
// x中1的奇偶性。
#define highest_bit1_index(x) (31 - __builtin_clz(x))
#define highest_bit1_index_ll(x) (63 - __builtin_clzll(x))
#define rep(i, a, n) for (int i = a; i < (n); i++)
#define per(i, a, n) for (int i = (n)-1; i >= a; i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define sz(x) ((int)(x).size())
typedef vector<int> vi;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef double db;
#if DEBUG
#define dbg(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl;
#else
#define dbg(x)
#endif

// For example: SegmentTree<int> st(n, [](int a, int b) { return max(a, b); });
template <typename T>
class SegmentTree {
 public:
  SegmentTree(int node_num, function<T(T, T)> f, T default_v = T())
      : f_(f), default_value_(default_v) {
    offset_ = 1;
    while (offset_ < node_num) offset_ *= 2;
    nodes_.resize(offset_ * 2, default_v);
  }
 
  // 将第k个值更新为a
  void Update(int k, T a) {
    // 叶子节点
    k += offset_ - 1;
    nodes_[k] = a;
    // 向上更新
    while (k > 0) {
      k = (k - 1) / 2;
      nodes_[k] = f_(nodes_[k * 2 + 1], nodes_[k * 2 + 2]);
    }
  }
 
  T Query(int a, int b) { return Query(a, b, 0, 0, offset_); }
 
 private:
  // 求[a,b)区间的目标值
  // 后面的参数是为了计算方便传入的
  // k是节点的编号，l,r表示这个节点代表区间[l,r)
  // 外部调用时，使用query(a,b,0,0,n);
  T Query(int a, int b, int k, int l, int r) {
    // 如果[a,b)和[l,r)不相交，返回0
    if (r <= a || b <= l) return default_value_;
    // 如果[a,b)完全包含[l,r)，返回当前节点值
    if (a <= l && r <= b)
      return nodes_[k];
    else {
      T v1 = Query(a, b, k * 2 + 1, l, (l + r) / 2);
      T v2 = Query(a, b, k * 2 + 2, (l + r) / 2, r);
      return f_(v1, v2);
    }
  }
  int offset_;
  vector<T> nodes_;
  function<T(T, T)> f_;
  T default_value_;
};

template <class T> 
class larsch {
  struct reduce_row;
  struct reduce_col;

  struct reduce_row {
    int n;
    std::function<T(int, int)> f;
    int cur_row;
    int state;
    std::unique_ptr<reduce_col> rec;

    reduce_row(int n_) : n(n_), f(), cur_row(0), state(0), rec() {
      const int m = n / 2;
      if (m != 0) {
        rec = std::make_unique<reduce_col>(m);
      }
    }

    void set_f(std::function<T(int, int)> f_) {
      f = f_;
      if (rec) {
        rec->set_f([&](int i, int j) -> T { return f(2 * i + 1, j); });
      }
    }

    int get_argmin() {
      const int cur_row_ = cur_row;
      cur_row += 1;
      if (cur_row_ % 2 == 0) {
        const int prev_argmin = state;
        const int next_argmin = [&]() {
          if (cur_row_ + 1 == n) {
            return n - 1;
          } else {
            return rec->get_argmin();
          }
        }();
        state = next_argmin;
        int ret = prev_argmin;
        for (int j = prev_argmin + 1; j <= next_argmin; j += 1) {
          if (f(cur_row_, ret) > f(cur_row_, j)) {
            ret = j;
          }
        }
        return ret;
      } else {
        if (f(cur_row_, state) <= f(cur_row_, cur_row_)) {
          return state;
        } else {
          return cur_row_;
        }
      }
    }
  };

  struct reduce_col {
    int n;
    std::function<T(int, int)> f;
    int cur_row;
    std::vector<int> cols;
    reduce_row rec;

    reduce_col(int n_) : n(n_), f(), cur_row(0), cols(), rec(n) {}

    void set_f(std::function<T(int, int)> f_) {
      f = f_;
      rec.set_f([&](int i, int j) -> T { return f(i, cols[j]); });
    }

    int get_argmin() {
      const int cur_row_ = cur_row;
      cur_row += 1;
      const auto cs = [&]() -> std::vector<int> {
        if (cur_row_ == 0) {
          return {{0}};
        } else {
          return {{2 * cur_row_ - 1, 2 * cur_row_}};
        }
      }();
      for (const int j : cs) {
        while ([&]() {
          const int size = cols.size();
          return size != cur_row_ && f(size - 1, cols.back()) > f(size - 1, j);
        }()) {
          cols.pop_back();
        }
        if (cols.size() != n) {
          cols.push_back(j);
        }
      }
      return cols[rec.get_argmin()];
    }
  };

  std::unique_ptr<reduce_row> base;

public:
  larsch(int n, std::function<T(int, int)> f)
      : base(std::make_unique<reduce_row>(n)) {
    base->set_f(f);
  }

  int get_argmin() { return base->get_argmin(); }
};

class Solution {
public:
    void Solve() {
        cout << fixed << setprecision(15);
        int N, L;
        while(cin >> N >> L) {
            constexpr ll INF = std::numeric_limits<ll>::max() / 2;

            vector<ll> a(N+1, 0);
            rep(i,1,N+1) cin>>a[i];
            SegmentTree<ll> st(N+1, [](ll a,ll b) {return max(a,b);}, -INF);
            rep(i,0,N+1) st.Update(i, a[i]);

            auto calc = [&]() {
                std::vector<ll> dist(N + 1, INF);
                dist[0] = 0;
                const auto f = [&](const int to_, const int from) -> ll {
                    const int to = to_ + 1;
                    if (to - from < L) { // to <= from
                        return INF;
                    } else {
                        return dist[from] - st.Query(from + 1, to + 1);
                    }
                };
                larsch<ll> larsch_(
                    N, [&](int i, int j) { return f(i, j); });
                for (int i = 0; i < N; i++) {
                    int argmin = larsch_.get_argmin();
                    // dbg(argmin);
                    dist[i + 1] = f(i, argmin);
                    // if (i+1==N+1) dbg(dist[N+1]);
                }
                // dbg(dist);
                return dist[N];
            };

            cout << -calc() << '\n';
        }
        cout.flush();
    }
private:
};

// # define FILE_IO 1
void set_io(const string &name = "") {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
#if FILE_IO
    if (!name.empty()) {
        freopen((name + ".in").c_str(), "r", stdin);
        freopen((name + ".out").c_str(), "w", stdout);
    }
#endif
}

int main() {
    set_io("tmp");
    Solution().Solve();

    return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 10616
final_rank: 12

code_snippet: #line 1 "larsch.test.cpp"
#define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=3086"

#line 2 "/Users/korogi/Desktop/cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "/Users/korogi/Desktop/cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "/Users/korogi/Desktop/cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) {
        os << '-';
        y *= -1;
    }
    std::vector<int> ny;
    while(y > 0) {
        ny.push_back(y % 10);
        y /= 10;
    }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "/Users/korogi/Desktop/cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "/Users/korogi/Desktop/cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "/Users/korogi/Desktop/cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "/Users/korogi/Desktop/cp-library/src/cp-template.hpp"

#line 1 "/Users/korogi/Desktop/cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F& f) {
    while(abs(ok - ng) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F& f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "/Users/korogi/Desktop/cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 2 "/Users/korogi/Desktop/cp-library/src/algorithm/larsch.hpp"

template < class T > class larsch {
    struct reduce_row;
    struct reduce_col;

    struct reduce_row {
        int n, cur_row, state;
        std::function<T(int,int)> f;
        std::unique_ptr<reduce_col> rec;

        reduce_row(int n_, std::function<T(int,int)> f_) : n(n_), cur_row(0), state(0), f(f_) {
            const int m = n / 2;
            if(m != 0) rec = std::make_unique<reduce_col>(m, [&](int i, int j) -> T { return f(2 * i + 1, j); });
        }

        int get_argmin() {
            const int cur_row_ = cur_row;
            cur_row += 1;
            if(cur_row_ % 2 == 0) {
                const int prev_argmin = state;
                const int next_argmin = state = (cur_row_ + 1 == n ? n - 1 : rec->get_argmin());
                int ret = prev_argmin;
                for(int j = prev_argmin + 1; j <= next_argmin; j += 1)
                    if(f(cur_row_, ret) > f(cur_row_, j)) ret = j;
                return ret;
            } else {
                return f(cur_row_, state) <= f(cur_row_, cur_row_) ? state : cur_row_;
            }
        }
    };

    struct reduce_col {
        int n, cur_row;
        std::vector<int> cols;
        std::function<T(int,int)> f;
        reduce_row rec;

        reduce_col(int n_, std::function<T(int,int)> f_) : n(n_), cur_row(0), f(f_), rec(n, [&](int i, int j) -> T { return f(i, cols[j]); }) {}

        int get_argmin() {
            const int cur_row_ = cur_row;
            cur_row += 1;
            const auto cs = [&]() -> std::vector<int> {
                if(cur_row_ == 0) return {0};
                return {2 * cur_row_ - 1, 2 * cur_row_};
            }();
            for(const int j : cs) {
                while(cols.size() != cur_row_ and f(cols.size() - 1, cols.back()) > f(cols.size() - 1, j)) cols.pop_back();
                if(cols.size() != n) cols.push_back(j);
            }
            return cols[rec.get_argmin()];
        }
    };

    std::unique_ptr<reduce_row> base;

  public:
    larsch(int n, std::function<T(int,int)> f) : base(std::make_unique<reduce_row>(n, f)) {}
    int get_argmin() { return base->get_argmin(); }
};
#line 2 "/Users/korogi/Desktop/cp-library/src/data_structure/linear_rmq.hpp"

template < class Compare >
class linear_rmq {
    int size;
    Compare cmp;
    static constexpr std::size_t BLOCK_SIZE = 16;
    using block_type = std::uint_least16_t;
    using size_type = std::size_t;
    std::vector<block_type> small;
    std::vector<std::vector<size_type>> large;

    size_type argmin_(const size_type i, const size_type j) const { return cmp(i, j) ? i : j; }
    size_type msb(size_type c) const { return 31 - __builtin_clz(c); }
    size_type ctz(const block_type c) const { return __builtin_ctz(c); }

  public:
    linear_rmq(const size_type size, const Compare& cmp) : size(size), cmp(cmp), small(size), large(1) {
        std::vector<size_type> st;
        for(size_type i : rep(size)) {
            while(not st.empty() and not cmp(st.back(), i)) st.pop_back();
            small[i] = (st.empty() ? 0 : small[st.back()]) | static_cast<block_type>(1) << (i % BLOCK_SIZE);
            st.emplace_back(i);
            if((i + 1) % BLOCK_SIZE == 0) {
                large[0].emplace_back(st[0]);
                st.clear();
            }
        }

        for(size_type i = 1; (i << 1) <= size / BLOCK_SIZE; i <<= 1) {
            const size_type csz = size / BLOCK_SIZE + 1 - (i << 1);
            std::vector<size_type> v(csz);
            for(size_type k : rep(csz)) v[k] = argmin_(large.back()[k], large.back()[k + i]);
            large.emplace_back(::std::move(v));
        }
    }

    // [first, last]
    size_type argmin(const size_type first, const size_type last) const {
        assert(first <= last and last < size);

        const size_type left = first / BLOCK_SIZE + 1;
        const size_type right = last / BLOCK_SIZE;
        if(left <= right) {
            size_type c1 = (left - 1) * BLOCK_SIZE + ctz(small[left * BLOCK_SIZE - 1] & ~static_cast<block_type>(0) << first % BLOCK_SIZE);
            size_type c2 = right      * BLOCK_SIZE + ctz(small[last]);
            size_type i = argmin_(c1, c2);
            if(left < right) {
                const size_type p = msb(right - left);
                size_type c3 = large[p][left];
                size_type c4 = large[p][right - (static_cast<size_type>(1) << p)];
                i = argmin_(i, argmin_(c3, c4));
            }
            return i;
        } else {
            return right * BLOCK_SIZE + ctz(small[last] & ~static_cast<block_type>(0) << first % BLOCK_SIZE);
        }
    }
};
#line 6 "larsch.test.cpp"

int main() {
    int N = in(), L = in();
    vector<int> a = in(N);
    linear_rmq rmq(N, [&](int i, int j) { return a[i] >= a[j]; });

    vector<ll> dp(N + 1, 0);
    auto f = [&](int l, int r) {
        if(r - l < L) return -ll(4e18);
        return dp[l] + a[rmq.argmin(l, r - 1)];
    };
    auto g = [&](int i, int j) { return -f(j, i + 1); };
    larsch<ll> larsch_(N, g);
    for(int i : rep(N)) dp[i + 1] = -g(i, larsch_.get_argmin());
    print(dp[N]);
}
accuracy: 1
time_ms: 30
memory_kb: 7132
final_rank: 1

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) {
        os << '-';
        y *= -1;
    }
    std::vector<int> ny;
    while(y > 0) {
        ny.push_back(y % 10);
        y /= 10;
    }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F& f) {
    while(abs(ok - ng) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F& f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "cp-library/src/data_structure/segtree.hpp"
template < class monoid > struct segtree {
    using S = typename monoid::set;

    segtree() : segtree(0) {}
    segtree(int n) : segtree(vector< S >(n, monoid::id())) {}
    segtree(int n, S s) : segtree(vector< S >(n, s)) {}
    segtree(const vector< S >& v) : _n(int(v.size())) {
        log = ceil_pow2(_n);
        size = 1 << log;
        d = vector< S >(2 * size, monoid::id());
        for(int i = 0; i < _n; i++) d[size + i] = v[i];
        for(int i = size - 1; i >= 1; i--) update(i);
    }
    // a[i] <- x
    void set(int i, S x) {
        assert(0 <= i && i < _n);
        i += size;
        d[i] = x;
        for(int p = 1; p <= log; p++) update(i >> p);
    }
    // a[i]
    S get(int i) {
        assert(0 <= i && i < _n);
        return d[i + size];
    }
    // [l, r)
    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        S sml = monoid::id(), smr = monoid::id();
        l += size, r += size;
        while(l < r) {
            if(l & 1) sml = monoid::op(sml, d[l++]);
            if(r & 1) smr = monoid::op(d[--r], smr);
            l >>= 1, r >>= 1;
        }
        return monoid::op(sml, smr);
    }
    S all_prod() { return d[1]; }
    template < class func > int max_right(int l, func f) {
        assert(0 <= l && l <= _n);
        assert(f(monoid::id()));
        if(l == _n) return _n;
        l += size;
        S sm = monoid::id();
        do {
            while(l % 2 == 0) l >>= 1;
            if(!f(monoid::op(sm, d[l]))) {
                while(l < size) {
                    l = 2 * l;
                    if(f(monoid::op(sm, d[l]))) {
                        sm = monoid::op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = monoid::op(sm, d[l]);
            l++;
        } while((l & -l) != l);
        return _n;
    }
    template < class func > int min_left(int r, func f) {
        assert(0 <= r && r <= _n);
        assert(f(monoid::id()));
        if(r == 0) return 0;
        r += size;
        S sm = monoid::id();
        do {
            r--;
            while(r > 1 && (r % 2)) r >>= 1;
            if(!f(monoid::op(d[r], sm))) {
                while(r < size) {
                    r = 2 * r + 1;
                    if(f(monoid::op(d[r], sm))) {
                        sm = monoid::op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = monoid::op(d[r], sm);
        } while((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    vector< S > d;
    int ceil_pow2(int n) { int x = 0; while((1U << x) < uint(n)) x++; return x; }
    void update(int k) { d[k] = monoid::op(d[2 * k], d[2 * k + 1]); }
};
#line 3 "cp-library/src/algebra/minmax.hpp"

template < class T > class min_monoid {
  public:
    using set = T;
    static constexpr T op(const T &l, const T &r) { return std::min(l, r); }
    static constexpr T id() { return std::numeric_limits< T >::max(); }
    static constexpr bool comm = true;
};

template < class T > class max_monoid {
  public:
    using set = T;
    static constexpr T op(const T &l, const T &r) { return std::max(l, r); }
    static constexpr T id() { return std::numeric_limits< T >::min(); }
    static constexpr bool comm = true;
};
#line 4 "LARSCH.cpp"

template < class T > class larsch {
    struct reduce_row;
    struct reduce_col;

    struct reduce_row {
        int n, cur_row, state;
        std::function<T(int,int)> f;
        std::unique_ptr<reduce_col> rec;

        reduce_row(int n_, std::function<T(int,int)> f_) : n(n_), cur_row(0), state(0), f(f_) {
            const int m = n / 2;
            if(m != 0) rec = std::make_unique<reduce_col>(m, [&](int i, int j) -> T { return f(2 * i + 1, j); });
        }

        int get_argmin() {
            const int cur_row_ = cur_row;
            cur_row += 1;
            if(cur_row_ % 2 == 0) {
                const int prev_argmin = state;
                const int next_argmin = state = (cur_row_ + 1 == n ? n - 1 : rec->get_argmin());
                int ret = prev_argmin;
                for(int j = prev_argmin + 1; j <= next_argmin; j += 1)
                    if(f(cur_row_, ret) > f(cur_row_, j)) ret = j;
                return ret;
            } else {
                return f(cur_row_, state) <= f(cur_row_, cur_row_) ? state : cur_row_;
            }
        }
    };

    struct reduce_col {
        int n, cur_row;
        std::vector<int> cols;
        std::function<T(int,int)> f;
        reduce_row rec;

        reduce_col(int n_, std::function<T(int,int)> f_) : n(n_), cur_row(0), f(f_), rec(n, [&](int i, int j) -> T { return f(i, cols[j]); }) {}

        int get_argmin() {
            const int cur_row_ = cur_row;
            cur_row += 1;
            const std::vector<int> cs = [&]() -> std::vector<int> {
                if(cur_row_ == 0) return {0};
                return {2 * cur_row_ - 1, 2 * cur_row_};
            }();
            for(const int j : cs) {
                while(cols.size() != cur_row_ and f(cols.size() - 1, cols.back()) > f(cols.size() - 1, j)) cols.pop_back();
                if(cols.size() != n) cols.push_back(j);
            }
            return cols[rec.get_argmin()];
        }
    };

    std::unique_ptr<reduce_row> base;

  public:
    larsch(int n, std::function<T(int,int)> f) : base(std::make_unique<reduce_row>(n, f)) {}
    int get_argmin() { return base->get_argmin(); }
};

int main() {
    int N = in(), L = in();
    vector<int> a = in(N);
    segtree< max_monoid<int> > seg(a);

    std::vector<ll> dp(N + 1, 0);
    auto f = [&](int l, int r) {
        if(r - l < L) return -ll(4e18);
        return dp[l] + seg.prod(l, r);
    };
    auto g = [&](int i, int j) { return -f(j, i + 1); };
    larsch<ll> larsch_(N, g);
    for(int i : rep(N)) dp[i + 1] = -g(i, larsch_.get_argmin());
    print(dp[N]);
}
accuracy: 1
time_ms: 80
memory_kb: 7836
final_rank: 3

code_snippet: #line 1 "test/aoj/aoj_3086.test.cpp"
#define PROBLEM "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=3086"

#line 2 "algorithm/monge_shortest_path.hpp"

#include <limits>
#include <vector>

namespace ebi {

template <class T, class F> std::vector<T> monge_shortest_path(int n, F f) {
    const T max = std::numeric_limits<T>::max();
    std::vector<int> argmin(n, 0);
    std::vector<T> dp(n, max);
    dp[0] = 0;
    auto get = [&](int i, int j) -> T {
        T val = f(j, i);
        if(val == max || dp[j] == max) return max;
        return dp[j] + val;
    };
    auto check = [&](int i, int j) -> void {
        T val = get(i, j);
        if (val < dp[i]) {
            dp[i] = val;
            argmin[i] = j;
        }
    };
    dp[n - 1] = get(n - 1, 0);
    auto dfs = [&](auto &&self, int l, int r) -> void {
        if (r - l == 1) return;
        int m = (l + r) >> 1;
        for (int i = argmin[l]; i <= argmin[r]; i++) {
            check(m, i);
        }
        self(self, l, m);
        for (int i = l + 1; i <= m; i++) {
            check(r, i);
        }
        self(self, m, r);
    };
    dfs(dfs, 0, n - 1);
    return dp;
}

}  // namespace ebi
#line 2 "data_structure/segtree.hpp"

#include <cassert>
#line 5 "data_structure/segtree.hpp"

namespace ebi {

template <class S, S (*op)(S, S), S (*e)()> struct segtree {
  private:
    int n;
    int sz;
    std::vector<S> data;

    void update(int i) {
        data[i] = op(data[2 * i], data[2 * i + 1]);
    }

  public:
    segtree(int n_) : segtree(std::vector<S>(n_, e())) {}
    segtree(const std::vector<S> &v) : n((int)v.size()), sz(1) {
        while (sz < n) sz *= 2;
        data = std::vector<S>(2 * sz, e());
        for (int i = 0; i < n; i++) {
            data[sz + i] = v[i];
        }
        for (int i = sz - 1; i >= 1; i--) update(i);
    }

    void set(int p, S x) {
        assert(0 <= p && p < n);
        p += sz;
        data[p] = x;
        while (p > 1) {
            p >>= 1;
            update(p);
        }
    }

    S get(int p) const {
        assert(0 <= p && p < n);
        return data[p + sz];
    }

    S prod(int l, int r) const {
        assert(0 <= l && l <= r && r <= n);
        S sml = e(), smr = e();
        l += sz;
        r += sz;
        while (l < r) {
            if (l & 1) sml = op(sml, data[l++]);
            if (r & 1) smr = op(data[--r], smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }

    S all_prod() const {
        return data[1];
    }

    template <class F> int max_right(int l, F f) const {
        assert(0 <= l && l < n);
        assert(f(e()));
        if (l == n) return n;
        l += sz;
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(op(sm, data[l]))) {
                while (l < sz) {
                    l = 2 * l;
                    if (f(op(sm, data[l]))) {
                        sm = op(sm, data[l]);
                        l++;
                    }
                }
                return l - sz;
            }
            sm = op(sm, data[l]);
            l++;
        } while ((l & -l) != l);
        return n;
    }

    template <class F> int min_left(int r, F f) const {
        assert(0 <= r && r <= n);
        assert(f(e()));
        if (r == 0) return 0;
        r += sz;
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(op(data[r], sm))) {
                while (r < sz) {
                    r = 2 * r + 1;
                    if (f(op(data[r], sm))) {
                        sm = op(data[r], sm);
                        r--;
                    }
                }
                return r + 1 - sz;
            }
            sm = op(data[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

    S operator[](int p) const {
        return data[sz + p];
    }
};

}  // namespace ebi

#include <bits/stdc++.h>

#define rep(i, a, n) for (int i = (int)(a); i < (int)(n); i++)
#define rrep(i, a, n) for (int i = ((int)(n)-1); i >= (int)(a); i--)
#define Rep(i, a, n) for (i64 i = (i64)(a); i < (i64)(n); i++)
#define RRep(i, a, n) for (i64 i = ((i64)(n)-i64(1)); i >= (i64)(a); i--)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()

#line 2 "template/debug_template.hpp"

#line 4 "template/debug_template.hpp"

namespace ebi {

#ifdef LOCAL
#define debug(...)                                                      \
    std::cerr << "LINE: " << __LINE__ << "  [" << #__VA_ARGS__ << "]:", \
        debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif

void debug_out() {
    std::cerr << std::endl;
}

template <typename Head, typename... Tail> void debug_out(Head h, Tail... t) {
    std::cerr << " " << h;
    if (sizeof...(t) > 0) std::cerr << " :";
    debug_out(t...);
}

}  // namespace ebi
#line 2 "template/int_alias.hpp"

#line 4 "template/int_alias.hpp"

namespace ebi {

using std::size_t;
using i8 = std::int8_t;
using u8 = std::uint8_t;
using i16 = std::int16_t;
using u16 = std::uint16_t;
using i32 = std::int32_t;
using u32 = std::uint32_t;
using i64 = std::int64_t;
using u64 = std::uint64_t;
using i128 = __int128_t;
using u128 = __uint128_t;

}  // namespace ebi
#line 2 "template/io.hpp"

#line 7 "template/io.hpp"

namespace ebi {

template <typename T1, typename T2>
std::ostream &operator<<(std::ostream &os, const std::pair<T1, T2> &pa) {
    return os << pa.first << " " << pa.second;
}

template <typename T1, typename T2>
std::istream &operator>>(std::istream &os, std::pair<T1, T2> &pa) {
    return os >> pa.first >> pa.second;
}

template <typename T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &vec) {
    for (std::size_t i = 0; i < vec.size(); i++)
        os << vec[i] << (i + 1 == vec.size() ? "" : " ");
    return os;
}

template <typename T>
std::istream &operator>>(std::istream &os, std::vector<T> &vec) {
    for (T &e : vec) std::cin >> e;
    return os;
}

template <typename T>
std::ostream &operator<<(std::ostream &os, const std::optional<T> &opt) {
    if (opt) {
        os << opt.value();
    } else {
        os << "invalid value";
    }
    return os;
}

void fast_io() {
    std::cout << std::fixed << std::setprecision(15);
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);
}

}  // namespace ebi
#line 2 "template/utility.hpp"

#line 5 "template/utility.hpp"

#line 7 "template/utility.hpp"

namespace ebi {

template <class T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}

template <class T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

template <class T> T safe_ceil(T a, T b) {
    if (a % b == 0)
        return a / b;
    else if (a >= 0)
        return (a / b) + 1;
    else
        return -((-a) / b);
}

template <class T> T safe_floor(T a, T b) {
    if (a % b == 0)
        return a / b;
    else if (a >= 0)
        return a / b;
    else
        return -((-a) / b) - 1;
}

constexpr i64 LNF = std::numeric_limits<i64>::max() / 4;

constexpr int INF = std::numeric_limits<int>::max() / 2;

const std::vector<int> dy = {1, 0, -1, 0, 1, 1, -1, -1};
const std::vector<int> dx = {0, 1, 0, -1, 1, -1, 1, -1};

}  // namespace ebi
#line 6 "test/aoj/aoj_3086.test.cpp"

namespace ebi {

i64 op(i64 a, i64 b) {
    return a < b ? a : b;
}

i64 e() {
    return LNF;
}

void main_() {
    int n, l;
    std::cin >> n >> l;
    std::vector<i64> a(n);
    std::cin >> a;
    rep(i, 0, n) a[i] = -a[i];
    segtree<i64, op, e> seg(a);
    auto f = [&](int i, int j) -> i64 {
        if (j - i < l) return std::numeric_limits<i64>::max();
        return seg.prod(i, j);
    };
    auto dp = monge_shortest_path<i64>(n + 1, f);
    std::cout << -dp[n] << '\n';
}

}  // namespace ebi

int main() {
    ebi::fast_io();
    int t = 1;
    // std::cin >> t;
    while (t--) {
        ebi::main_();
    }
    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 10060
final_rank: 4

code_snippet: #include <bits/stdc++.h>

#define rep(i, a, n) for (int i = (int)(a); i < (int)(n); i++)
#define rrep(i, a, n) for (int i = ((int)(n)-1); i >= (int)(a); i--)
#define Rep(i, a, n) for (i64 i = (i64)(a); i < (i64)(n); i++)
#define RRep(i, a, n) for (i64 i = ((i64)(n)-i64(1)); i >= (i64)(a); i--)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()

#line 2 "template/debug_template.hpp"

#line 4 "template/debug_template.hpp"

namespace ebi {

#ifdef LOCAL
#define debug(...)                                                      \
    std::cerr << "LINE: " << __LINE__ << "  [" << #__VA_ARGS__ << "]:", \
        debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif

void debug_out() {
    std::cerr << std::endl;
}

template <typename Head, typename... Tail> void debug_out(Head h, Tail... t) {
    std::cerr << " " << h;
    if (sizeof...(t) > 0) std::cerr << " :";
    debug_out(t...);
}

}  // namespace ebi
#line 2 "template/int_alias.hpp"

#line 4 "template/int_alias.hpp"

namespace ebi {

using std::size_t;
using i8 = std::int8_t;
using u8 = std::uint8_t;
using i16 = std::int16_t;
using u16 = std::uint16_t;
using i32 = std::int32_t;
using u32 = std::uint32_t;
using i64 = std::int64_t;
using u64 = std::uint64_t;
using i128 = __int128_t;
using u128 = __uint128_t;

}  // namespace ebi
#line 2 "template/io.hpp"

#line 7 "template/io.hpp"

namespace ebi {

template <typename T1, typename T2>
std::ostream &operator<<(std::ostream &os, const std::pair<T1, T2> &pa) {
    return os << pa.first << " " << pa.second;
}

template <typename T1, typename T2>
std::istream &operator>>(std::istream &os, std::pair<T1, T2> &pa) {
    return os >> pa.first >> pa.second;
}

template <typename T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &vec) {
    for (std::size_t i = 0; i < vec.size(); i++)
        os << vec[i] << (i + 1 == vec.size() ? "" : " ");
    return os;
}

template <typename T>
std::istream &operator>>(std::istream &os, std::vector<T> &vec) {
    for (T &e : vec) std::cin >> e;
    return os;
}

template <typename T>
std::ostream &operator<<(std::ostream &os, const std::optional<T> &opt) {
    if (opt) {
        os << opt.value();
    } else {
        os << "invalid value";
    }
    return os;
}

void fast_io() {
    std::cout << std::fixed << std::setprecision(15);
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);
}

}  // namespace ebi
#line 2 "template/utility.hpp"

#line 5 "template/utility.hpp"

#line 7 "template/utility.hpp"

namespace ebi {

template <class T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}

template <class T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

template <class T> T safe_ceil(T a, T b) {
    if (a % b == 0)
        return a / b;
    else if (a >= 0)
        return (a / b) + 1;
    else
        return -((-a) / b);
}

template <class T> T safe_floor(T a, T b) {
    if (a % b == 0)
        return a / b;
    else if (a >= 0)
        return a / b;
    else
        return -((-a) / b) - 1;
}

constexpr i64 LNF = std::numeric_limits<i64>::max() / 4;

constexpr int INF = std::numeric_limits<int>::max() / 2;

const std::vector<int> dy = {1, 0, -1, 0, 1, 1, -1, -1};
const std::vector<int> dx = {0, 1, 0, -1, 1, -1, 1, -1};

}  // namespace ebi
#line 2 "data_structure/segtree.hpp"

#line 5 "data_structure/segtree.hpp"

namespace ebi {

template <class S, S (*op)(S, S), S (*e)()> struct segtree {
  private:
    int n;
    int sz;
    std::vector<S> data;

    void update(int i) {
        data[i] = op(data[2 * i], data[2 * i + 1]);
    }

  public:
    segtree(int n_) : segtree(std::vector<S>(n_, e())) {}
    segtree(const std::vector<S> &v) : n((int)v.size()), sz(1) {
        while (sz < n) sz *= 2;
        data = std::vector<S>(2 * sz, e());
        for (int i = 0; i < n; i++) {
            data[sz + i] = v[i];
        }
        for (int i = sz - 1; i >= 1; i--) update(i);
    }

    void set(int p, S x) {
        assert(0 <= p && p < n);
        p += sz;
        data[p] = x;
        while (p > 1) {
            p >>= 1;
            update(p);
        }
    }

    S get(int p) const {
        assert(0 <= p && p < n);
        return data[p + sz];
    }

    S prod(int l, int r) const {
        assert(0 <= l && l <= r && r <= n);
        S sml = e(), smr = e();
        l += sz;
        r += sz;
        while (l < r) {
            if (l & 1) sml = op(sml, data[l++]);
            if (r & 1) smr = op(data[--r], smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }

    S all_prod() const {
        return data[1];
    }

    template <class F> int max_right(int l, F f) const {
        assert(0 <= l && l < n);
        assert(f(e()));
        if (l == n) return n;
        l += sz;
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(op(sm, data[l]))) {
                while (l < sz) {
                    l = 2 * l;
                    if (f(op(sm, data[l]))) {
                        sm = op(sm, data[l]);
                        l++;
                    }
                }
                return l - sz;
            }
            sm = op(sm, data[l]);
            l++;
        } while ((l & -l) != l);
        return n;
    }

    template <class F> int min_left(int r, F f) const {
        assert(0 <= r && r <= n);
        assert(f(e()));
        if (r == 0) return 0;
        r += sz;
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(op(data[r], sm))) {
                while (r < sz) {
                    r = 2 * r + 1;
                    if (f(op(data[r], sm))) {
                        sm = op(data[r], sm);
                        r--;
                    }
                }
                return r + 1 - sz;
            }
            sm = op(data[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

    S operator[](int p) const {
        return data[sz + p];
    }
};

}  // namespace ebi
#line 3 "a.cpp"

namespace ebi {

template<class T, class F>
std::vector<T> monge_shortest_path(int n, F f) {
    const T max = std::numeric_limits<T>::max();
    std::vector<int> argmin(n, 0);
    std::vector<T> dp(n, max);
    dp[0] = 0;
    auto get = [&](int i, int j) -> T {
        return dp[j] + f(j, i);
    };
    auto check = [&](int i, int j) -> void {
        T val = get(i, j);
        if(val <= dp[i]) {
            dp[i] = val;
            argmin[i] = j;
        }
    };
    dp[n-1] = get(n-1, 0);
    auto dfs = [&](auto &&self, int l, int r) -> void {
        if(r - l == 1) return;
        int m = (l + r) >> 1;
        for(int i = argmin[l]; i <= argmin[r]; i++) {
            check(m, i);
        }
        self(self, l, m);
        for(int i = l + 1; i <= m; i++) {
            check(r, i);
        }
        self(self, m, r);
    };
    dfs(dfs, 0, n-1);
    return dp;
}

i64 op(i64 a, i64 b) {
    return a < b ? a : b;
}

i64 e() {
    return LNF;
}

void main_() {
    int n,l;
    std::cin >> n >> l;
    std::vector<i64> a(n);
    std::cin >> a;
    rep(i,0,n) a[i] = -a[i];
    segtree<i64, op, e> seg(a);
    auto f = [&](int i, int j) -> i64 {
        if(j - i < l) return LNF;
        return seg.prod(i, j);
    };
    auto dp = monge_shortest_path<i64>(n+1, f);
    std::cout << -dp[n] << '\n';
}

}  // namespace ebi

int main() {
    ebi::fast_io();
    int t = 1;
    // std::cin >> t;
    while (t--) {
        ebi::main_();
    }
    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 10144
final_rank: 7

code_snippet: #include <bits/stdc++.h>

#define rep(i, a, n) for (int i = (int)(a); i < (int)(n); i++)
#define rrep(i, a, n) for (int i = ((int)(n)-1); i >= (int)(a); i--)
#define Rep(i, a, n) for (i64 i = (i64)(a); i < (i64)(n); i++)
#define RRep(i, a, n) for (i64 i = ((i64)(n)-i64(1)); i >= (i64)(a); i--)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()

#line 2 "template/debug_template.hpp"

#line 4 "template/debug_template.hpp"

namespace ebi {

#ifdef LOCAL
#define debug(...)                                                      \
    std::cerr << "LINE: " << __LINE__ << "  [" << #__VA_ARGS__ << "]:", \
        debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif

void debug_out() {
    std::cerr << std::endl;
}

template <typename Head, typename... Tail> void debug_out(Head h, Tail... t) {
    std::cerr << " " << h;
    if (sizeof...(t) > 0) std::cerr << " :";
    debug_out(t...);
}

}  // namespace ebi
#line 2 "template/int_alias.hpp"

#line 4 "template/int_alias.hpp"

namespace ebi {

using std::size_t;
using i8 = std::int8_t;
using u8 = std::uint8_t;
using i16 = std::int16_t;
using u16 = std::uint16_t;
using i32 = std::int32_t;
using u32 = std::uint32_t;
using i64 = std::int64_t;
using u64 = std::uint64_t;
using i128 = __int128_t;
using u128 = __uint128_t;

}  // namespace ebi
#line 2 "template/io.hpp"

#line 7 "template/io.hpp"

namespace ebi {

template <typename T1, typename T2>
std::ostream &operator<<(std::ostream &os, const std::pair<T1, T2> &pa) {
    return os << pa.first << " " << pa.second;
}

template <typename T1, typename T2>
std::istream &operator>>(std::istream &os, std::pair<T1, T2> &pa) {
    return os >> pa.first >> pa.second;
}

template <typename T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &vec) {
    for (std::size_t i = 0; i < vec.size(); i++)
        os << vec[i] << (i + 1 == vec.size() ? "" : " ");
    return os;
}

template <typename T>
std::istream &operator>>(std::istream &os, std::vector<T> &vec) {
    for (T &e : vec) std::cin >> e;
    return os;
}

template <typename T>
std::ostream &operator<<(std::ostream &os, const std::optional<T> &opt) {
    if (opt) {
        os << opt.value();
    } else {
        os << "invalid value";
    }
    return os;
}

void fast_io() {
    std::cout << std::fixed << std::setprecision(15);
    std::cin.tie(nullptr);
    std::ios::sync_with_stdio(false);
}

}  // namespace ebi
#line 2 "template/utility.hpp"

#line 5 "template/utility.hpp"

#line 7 "template/utility.hpp"

namespace ebi {

template <class T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}

template <class T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

template <class T> T safe_ceil(T a, T b) {
    if (a % b == 0)
        return a / b;
    else if (a >= 0)
        return (a / b) + 1;
    else
        return -((-a) / b);
}

template <class T> T safe_floor(T a, T b) {
    if (a % b == 0)
        return a / b;
    else if (a >= 0)
        return a / b;
    else
        return -((-a) / b) - 1;
}

constexpr i64 LNF = std::numeric_limits<i64>::max() / 4;

constexpr int INF = std::numeric_limits<int>::max() / 2;

const std::vector<int> dy = {1, 0, -1, 0, 1, 1, -1, -1};
const std::vector<int> dx = {0, 1, 0, -1, 1, -1, 1, -1};

}  // namespace ebi
#line 2 "data_structure/segtree.hpp"

#line 5 "data_structure/segtree.hpp"

namespace ebi {

template <class S, S (*op)(S, S), S (*e)()> struct segtree {
  private:
    int n;
    int sz;
    std::vector<S> data;

    void update(int i) {
        data[i] = op(data[2 * i], data[2 * i + 1]);
    }

  public:
    segtree(int n_) : segtree(std::vector<S>(n_, e())) {}
    segtree(const std::vector<S> &v) : n((int)v.size()), sz(1) {
        while (sz < n) sz *= 2;
        data = std::vector<S>(2 * sz, e());
        for (int i = 0; i < n; i++) {
            data[sz + i] = v[i];
        }
        for (int i = sz - 1; i >= 1; i--) update(i);
    }

    void set(int p, S x) {
        assert(0 <= p && p < n);
        p += sz;
        data[p] = x;
        while (p > 1) {
            p >>= 1;
            update(p);
        }
    }

    S get(int p) const {
        assert(0 <= p && p < n);
        return data[p + sz];
    }

    S prod(int l, int r) const {
        assert(0 <= l && l <= r && r <= n);
        S sml = e(), smr = e();
        l += sz;
        r += sz;
        while (l < r) {
            if (l & 1) sml = op(sml, data[l++]);
            if (r & 1) smr = op(data[--r], smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }

    S all_prod() const {
        return data[1];
    }

    template <class F> int max_right(int l, F f) const {
        assert(0 <= l && l < n);
        assert(f(e()));
        if (l == n) return n;
        l += sz;
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(op(sm, data[l]))) {
                while (l < sz) {
                    l = 2 * l;
                    if (f(op(sm, data[l]))) {
                        sm = op(sm, data[l]);
                        l++;
                    }
                }
                return l - sz;
            }
            sm = op(sm, data[l]);
            l++;
        } while ((l & -l) != l);
        return n;
    }

    template <class F> int min_left(int r, F f) const {
        assert(0 <= r && r <= n);
        assert(f(e()));
        if (r == 0) return 0;
        r += sz;
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(op(data[r], sm))) {
                while (r < sz) {
                    r = 2 * r + 1;
                    if (f(op(data[r], sm))) {
                        sm = op(data[r], sm);
                        r--;
                    }
                }
                return r + 1 - sz;
            }
            sm = op(data[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

    S operator[](int p) const {
        return data[sz + p];
    }
};

}  // namespace ebi
#line 3 "a.cpp"

namespace ebi {

template<class T, class F>
std::vector<T> monge_shortest_path(int n, F f) {
    const T max = LNF;
    std::vector<int> argmin(n, 0);
    std::vector<T> dp(n, max);
    dp[0] = 0;
    auto get = [&](int i, int j) -> T {
        return dp[j] + f(j, i);
    };
    auto check = [&](int i, int j) -> void {
        T val = get(i, j);
        if(val <= dp[i]) {
            dp[i] = val;
            argmin[i] = j;
        }
    };
    dp[n-1] = get(n-1, 0);
    auto dfs = [&](auto &&self, int l, int r) -> void {
        if(r - l == 1) return;
        int m = (l + r) >> 1;
        for(int i = argmin[l]; i <= argmin[r]; i++) {
            check(m, i);
        }
        self(self, l, m);
        for(int i = l + 1; i <= m; i++) {
            check(r, i);
        }
        self(self, m, r);
    };
    dfs(dfs, 0, n-1);
    return dp;
}

i64 op(i64 a, i64 b) {
    return a < b ? a : b;
}

i64 e() {
    return LNF;
}

void main_() {
    int n,l;
    std::cin >> n >> l;
    std::vector<i64> a(n);
    std::cin >> a;
    rep(i,0,n) a[i] = -a[i];
    segtree<i64, op, e> seg(a);
    auto f = [&](int i, int j) -> i64 {
        if(j - i < l) return LNF;
        return seg.prod(i, j);
    };
    auto dp = monge_shortest_path<i64>(n+1, f);
    std::cout << -dp[n] << '\n';
}

}  // namespace ebi

int main() {
    ebi::fast_io();
    int t = 1;
    // std::cin >> t;
    while (t--) {
        ebi::main_();
    }
    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 10132
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define sz(x) int(x.size())
#define all(x) x.begin(), x.end()

template <class T> using vc = vector<T>;
template <class T> using vvc = vc<vc<T>>;

using ll = int64_t;
using vi = vc<int>;
using pii = pair<int, int>;

template <class F>
struct ycr {
	F f;
	
	template <class T>
	explicit ycr(T&& f_) : f(forward<T>(f_)) {}

	template <class... Args>
	decltype(auto) operator()(Args&&... args) {
		return f(ref(*this), forward<Args>(args)...);
	}
};
template <class F>
decltype(auto) yc(F&& f) {
	return ycr<decay_t<F>>(forward<F>(f));
}

template <class T, class F>
vc<T> monge_shortest_path(int n, F f) {
	const T inf = numeric_limits<T>::max() / 4;
	vc<T> dp(n+1, inf);
	vi x(n+1, 0);
	auto update = [&](int s, int t) {
		if (s >= t) return;
		T v = dp[s] + f(s, t);
		if (v < dp[t]) {
			dp[t] = v;
			x[t] = s;
		}
	};
	dp[0] = 0;
	update(0, n);
	yc([&](auto self, int l, int r) -> void {
		if (l+1 >= r) return;
		int m = (l+r)/2;
		for (int i = x[l]; i <= x[r]; i++) update(i, m);
		self(l, m);
		for (int i = l+1; i <= m; i++) update(i, r);
		self(m, r);
	})(0, n);
	return dp;
}

int main() {
	ios_base::sync_with_stdio(false), cin.tie(nullptr);
	cout << fixed << setprecision(20);

	int N, L; cin >> N >> L;
	const int S = 1 << (N <= 1 ? 0 : 32 - __builtin_clz(N-1));
	const int INF = 1.01e9;
	vector<int> seg(2*S, -INF);
	for (int i = 0; i < N; i++) {
		int a; cin >> a;
		seg[S+i] = a;
	}
	for (int i = S-1; i >= 1; i--) seg[i] = max(seg[2*i], seg[2*i+1]);

	const ll INFLL = numeric_limits<ll>::max() / 4;
	cout << -monge_shortest_path<ll>(N, [&](int l, int r) -> ll {
		assert(0 <= l && l < r && r <= N);
		if (r-l < L) return +INFLL;
		int v = -INF;
		for (int a = S+l, b = S+r; a < b; a /= 2, b /= 2) {
			if (a & 1) v = max(v, seg[a++]);
			if (b & 1) v = max(v, seg[--b]);
		}
		assert(v > -INF);
		return -v;
	})[N] << '\n';
}
accuracy: 1
time_ms: 130
memory_kb: 7012
final_rank: 2

code_snippet: /**
 *  date : 2023-05-23 20:20:43
 */

#define NDEBUG
using namespace std;

// intrinstic
#include <immintrin.h>

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cfenv>
#include <cfloat>
#include <chrono>
#include <cinttypes>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdarg>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fstream>
#include <functional>
#include <initializer_list>
#include <iomanip>
#include <ios>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <streambuf>
#include <string>
#include <tuple>
#include <type_traits>
#include <typeinfo>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

// utility
namespace Nyaan {
using ll = long long;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;

template <typename T>
using V = vector<T>;
template <typename T>
using VV = vector<vector<T>>;
using vi = vector<int>;
using vl = vector<long long>;
using vd = V<double>;
using vs = V<string>;
using vvi = vector<vector<int>>;
using vvl = vector<vector<long long>>;

template <typename T, typename U>
struct P : pair<T, U> {
  template <typename... Args>
  P(Args... args) : pair<T, U>(args...) {}

  using pair<T, U>::first;
  using pair<T, U>::second;

  P &operator+=(const P &r) {
    first += r.first;
    second += r.second;
    return *this;
  }
  P &operator-=(const P &r) {
    first -= r.first;
    second -= r.second;
    return *this;
  }
  P &operator*=(const P &r) {
    first *= r.first;
    second *= r.second;
    return *this;
  }
  template <typename S>
  P &operator*=(const S &r) {
    first *= r, second *= r;
    return *this;
  }
  P operator+(const P &r) const { return P(*this) += r; }
  P operator-(const P &r) const { return P(*this) -= r; }
  P operator*(const P &r) const { return P(*this) *= r; }
  template <typename S>
  P operator*(const S &r) const {
    return P(*this) *= r;
  }
  P operator-() const { return P{-first, -second}; }
};

using pl = P<ll, ll>;
using pi = P<int, int>;
using vp = V<pl>;

constexpr int inf = 1001001001;
constexpr long long infLL = 4004004004004004004LL;

template <typename T>
int sz(const T &t) {
  return t.size();
}

template <typename T, typename U>
inline bool amin(T &x, U y) {
  return (y < x) ? (x = y, true) : false;
}
template <typename T, typename U>
inline bool amax(T &x, U y) {
  return (x < y) ? (x = y, true) : false;
}

template <typename T>
inline T Max(const vector<T> &v) {
  return *max_element(begin(v), end(v));
}
template <typename T>
inline T Min(const vector<T> &v) {
  return *min_element(begin(v), end(v));
}
template <typename T>
inline long long Sum(const vector<T> &v) {
  return accumulate(begin(v), end(v), 0LL);
}

template <typename T>
int lb(const vector<T> &v, const T &a) {
  return lower_bound(begin(v), end(v), a) - begin(v);
}
template <typename T>
int ub(const vector<T> &v, const T &a) {
  return upper_bound(begin(v), end(v), a) - begin(v);
}

constexpr long long TEN(int n) {
  long long ret = 1, x = 10;
  for (; n; x *= x, n >>= 1) ret *= (n & 1 ? x : 1);
  return ret;
}

template <typename T, typename U>
pair<T, U> mkp(const T &t, const U &u) {
  return make_pair(t, u);
}

template <typename T>
vector<T> mkrui(const vector<T> &v, bool rev = false) {
  vector<T> ret(v.size() + 1);
  if (rev) {
    for (int i = int(v.size()) - 1; i >= 0; i--) ret[i] = v[i] + ret[i + 1];
  } else {
    for (int i = 0; i < int(v.size()); i++) ret[i + 1] = ret[i] + v[i];
  }
  return ret;
};

template <typename T>
vector<T> mkuni(const vector<T> &v) {
  vector<T> ret(v);
  sort(ret.begin(), ret.end());
  ret.erase(unique(ret.begin(), ret.end()), ret.end());
  return ret;
}

template <typename F>
vector<int> mkord(int N,F f) {
  vector<int> ord(N);
  iota(begin(ord), end(ord), 0);
  sort(begin(ord), end(ord), f);
  return ord;
}

template <typename T>
vector<int> mkinv(vector<T> &v) {
  int max_val = *max_element(begin(v), end(v));
  vector<int> inv(max_val + 1, -1);
  for (int i = 0; i < (int)v.size(); i++) inv[v[i]] = i;
  return inv;
}

vector<int> mkiota(int n) {
  vector<int> ret(n);
  iota(begin(ret), end(ret), 0);
  return ret;
}

template <typename T>
T mkrev(const T &v) {
  T w{v};
  reverse(begin(w), end(w));
  return w;
}

template <typename T>
bool nxp(vector<T> &v) {
  return next_permutation(begin(v), end(v));
}

template <typename T>
using minpq = priority_queue<T, vector<T>, greater<T>>;

}  // namespace Nyaan

// bit operation
namespace Nyaan {
__attribute__((target("popcnt"))) inline int popcnt(const u64 &a) {
  return _mm_popcnt_u64(a);
}
inline int lsb(const u64 &a) { return a ? __builtin_ctzll(a) : 64; }
inline int ctz(const u64 &a) { return a ? __builtin_ctzll(a) : 64; }
inline int msb(const u64 &a) { return a ? 63 - __builtin_clzll(a) : -1; }
template <typename T>
inline int gbit(const T &a, int i) {
  return (a >> i) & 1;
}
template <typename T>
inline void sbit(T &a, int i, bool b) {
  if (gbit(a, i) != b) a ^= T(1) << i;
}
constexpr long long PW(int n) { return 1LL << n; }
constexpr long long MSK(int n) { return (1LL << n) - 1; }
}  // namespace Nyaan

// inout
namespace Nyaan {

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << p.first << " " << p.second;
  return os;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first >> p.second;
  return is;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  int s = (int)v.size();
  for (int i = 0; i < s; i++) os << (i ? " " : "") << v[i];
  return os;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (auto &x : v) is >> x;
  return is;
}

istream &operator>>(istream &is, __int128_t &x) {
  string S;
  is >> S;
  x = 0;
  int flag = 0;
  for (auto &c : S) {
    if (c == '-') {
      flag = true;
      continue;
    }
    x *= 10;
    x += c - '0';
  }
  if (flag) x = -x;
  return is;
}

istream &operator>>(istream &is, __uint128_t &x) {
  string S;
  is >> S;
  x = 0;
  for (auto &c : S) {
    x *= 10;
    x += c - '0';
  }
  return is;
}

ostream &operator<<(ostream &os, __int128_t x) {
  if (x == 0) return os << 0;
  if (x < 0) os << '-', x = -x;
  string S;
  while (x) S.push_back('0' + x % 10), x /= 10;
  reverse(begin(S), end(S));
  return os << S;
}
ostream &operator<<(ostream &os, __uint128_t x) {
  if (x == 0) return os << 0;
  string S;
  while (x) S.push_back('0' + x % 10), x /= 10;
  reverse(begin(S), end(S));
  return os << S;
}

void in() {}
template <typename T, class... U>
void in(T &t, U &...u) {
  cin >> t;
  in(u...);
}

void out() { cout << "\n"; }
template <typename T, class... U, char sep = ' '>
void out(const T &t, const U &...u) {
  cout << t;
  if (sizeof...(u)) cout << sep;
  out(u...);
}

struct IoSetupNya {
  IoSetupNya() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);
    cerr << fixed << setprecision(7);
  }
} iosetupnya;

}  // namespace Nyaan

// debug

#ifdef NyaanDebug
#define trc(...) (void(0))
#else
#define trc(...) (void(0))
#endif

#ifdef NyaanLocal
#define trc2(...) (void(0))
#else
#define trc2(...) (void(0))
#endif

// macro
#define each(x, v) for (auto&& x : v)
#define each2(x, y, v) for (auto&& [x, y] : v)
#define all(v) (v).begin(), (v).end()
#define rep(i, N) for (long long i = 0; i < (long long)(N); i++)
#define repr(i, N) for (long long i = (long long)(N)-1; i >= 0; i--)
#define rep1(i, N) for (long long i = 1; i <= (long long)(N); i++)
#define repr1(i, N) for (long long i = (N); (long long)(i) > 0; i--)
#define reg(i, a, b) for (long long i = (a); i < (b); i++)
#define regr(i, a, b) for (long long i = (b)-1; i >= (a); i--)
#define fi first
#define se second
#define ini(...)   \
  int __VA_ARGS__; \
  in(__VA_ARGS__)
#define inl(...)         \
  long long __VA_ARGS__; \
  in(__VA_ARGS__)
#define ins(...)      \
  string __VA_ARGS__; \
  in(__VA_ARGS__)
#define in2(s, t)                           \
  for (int i = 0; i < (int)s.size(); i++) { \
    in(s[i], t[i]);                         \
  }
#define in3(s, t, u)                        \
  for (int i = 0; i < (int)s.size(); i++) { \
    in(s[i], t[i], u[i]);                   \
  }
#define in4(s, t, u, v)                     \
  for (int i = 0; i < (int)s.size(); i++) { \
    in(s[i], t[i], u[i], v[i]);             \
  }
#define die(...)             \
  do {                       \
    Nyaan::out(__VA_ARGS__); \
    return;                  \
  } while (0)

namespace Nyaan {
void solve();
}
int main() { Nyaan::solve(); }

//

using namespace std;

// https://noshi91.hatenablog.com/entry/2023/02/18/005856
// 辺コストが monge である DAG の 0 - i 最短路
template <typename T>
vector<T> monge_shortest_path(int N, const function<T(int, int)>& f) {
  T INF = (T{1} << (sizeof(T) * 8 - 2)) - 1;
  vector<T> dp(N + 1, INF);
  vector<int> x(N + 1, 0);
  auto check = [&](int from, int to) {
    if (from >= to) return;
    T cost = f(from, to);
    if (dp[from] + cost < dp[to]) dp[to] = dp[from] + cost, x[to] = from;
  };
  auto dfs = [&](auto rc, int l, int r) -> void {
    if (l + 1 >= r) return;
    int m = (l + r) / 2;
    for (int i = x[l]; i <= x[r]; i++) check(i, m);
    rc(rc, l, m);
    for (int i = l + 1; i <= m; i++) check(i, r);
    rc(rc, m, r);
  };
  dp[0] = 0, check(0, N), dfs(dfs, 0, N);
  return dp;
}

/**
 * @brief monge グラフ上の最短路
 */

//

template <typename T, typename F>
struct SegmentTree {
  int N;
  int size;
  vector<T> seg;
  const F f;
  const T I;

  SegmentTree(F _f, const T &I_) : N(0), size(0), f(_f), I(I_) {}

  SegmentTree(int _N, F _f, const T &I_) : f(_f), I(I_) { init(_N); }

  SegmentTree(const vector<T> &v, F _f, T I_) : f(_f), I(I_) {
    init(v.size());
    for (int i = 0; i < (int)v.size(); i++) {
      seg[i + size] = v[i];
    }
    build();
  }

  void init(int _N) {
    N = _N;
    size = 1;
    while (size < N) size <<= 1;
    seg.assign(2 * size, I);
  }

  void set(int k, T x) { seg[k + size] = x; }

  void build() {
    for (int k = size - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k], seg[2 * k + 1]);
    }
  }

  void update(int k, T x) {
    k += size;
    seg[k] = x;
    while (k >>= 1) {
      seg[k] = f(seg[2 * k], seg[2 * k + 1]);
    }
  }

  void add(int k, T x) {
    k += size;
    seg[k] += x;
    while (k >>= 1) {
      seg[k] = f(seg[2 * k], seg[2 * k + 1]);
    }
  }

  // query to [a, b)
  T query(int a, int b) {
    T L = I, R = I;
    for (a += size, b += size; a < b; a >>= 1, b >>= 1) {
      if (a & 1) L = f(L, seg[a++]);
      if (b & 1) R = f(seg[--b], R);
    }
    return f(L, R);
  }

  T &operator[](const int &k) { return seg[k + size]; }

  // check(a[l] * ...  * a[r-1]) が true となる最大の r
  // (右端まですべて true なら N を返す)
  template <class C>
  int max_right(int l, C check) {
    assert(0 <= l && l <= N);
    assert(check(I) == true);
    if (l == N) return N;
    l += size;
    T sm = I;
    do {
      while (l % 2 == 0) l >>= 1;
      if (!check(f(sm, seg[l]))) {
        while (l < size) {
          l = (2 * l);
          if (check(f(sm, seg[l]))) {
            sm = f(sm, seg[l]);
            l++;
          }
        }
        return l - size;
      }
      sm = f(sm, seg[l]);
      l++;
    } while ((l & -l) != l);
    return N;
  }

  // check(a[l] * ... * a[r-1]) が true となる最小の l
  // (左端まで true なら 0 を返す)
  template <typename C>
  int min_left(int r, C check) {
    assert(0 <= r && r <= N);
    assert(check(I) == true);
    if (r == 0) return 0;
    r += size;
    T sm = I;
    do {
      r--;
      while (r > 1 && (r % 2)) r >>= 1;
      if (!check(f(seg[r], sm))) {
        while (r < size) {
          r = (2 * r + 1);
          if (check(f(seg[r], sm))) {
            sm = f(seg[r], sm);
            r--;
          }
        }
        return r + 1 - size;
      }
      sm = f(seg[r], sm);
    } while ((r & -r) != r);
    return 0;
  }
};
using namespace Nyaan;

void q() {
  inl(N, L);
  vl d(N);
  in(d);
  each(x, d) x = -x;
  SegmentTree seg(
      d, [](ll a, ll b) { return min(a, b); }, infLL);
  auto ans = monge_shortest_path<ll>(N, [&](int l, int r) -> ll {
    if (r - l < L) return infLL;
    return seg.query(l, r);
  });
  out(-ans[N]);
}

void Nyaan::solve() {
  int t = 1;
  // in(t);
  while (t--) q();
}
accuracy: 1
time_ms: 100
memory_kb: 10092
final_rank: 8

code_snippet: #include<bits/stdc++.h>

using namespace std;

using int64 = long long;
const int mod = 1e9 + 7;

const int64 infll = (1LL << 62) - 1;
const int inf = (1 << 30) - 1;

struct IoSetup {
  IoSetup() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
    cerr << fixed << setprecision(10);
  }
} iosetup;


template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  os << p.first << " " << p.second;
  return os;
}

template<typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &p) {
  is >> p.first >> p.second;
  return is;
}

template<typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (int i = 0; i < (int) v.size(); i++) {
    os << v[i] << (i + 1 != v.size() ? " " : "");
  }
  return os;
}

template<typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (T &in : v) is >> in;
  return is;
}

template<typename T1, typename T2>
inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); }

template<typename T1, typename T2>
inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); }

template<typename T = int64>
vector<T> make_v(size_t a) {
  return vector<T>(a);
}

template<typename T, typename... Ts>
auto make_v(size_t a, Ts... ts) {
  return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}

template<typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type fill_v(T &t, const V &v) {
  t = v;
}

template<typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type fill_v(T &t, const V &v) {
  for (auto &e : t) fill_v(e, v);
}

template<typename F>
struct FixPoint : F {
  explicit FixPoint(F &&f) : F(forward<F>(f)) {}

  template<typename... Args>
  decltype(auto) operator()(Args &&... args) const {
    return F::operator()(*this, forward<Args>(args)...);
  }
};

template<typename F>
inline decltype(auto) MFP(F &&f) {
  return FixPoint<F>{forward<F>(f)};
}

#line 1 "dp/monotone-minima.cpp"

/**
 * @brief Monotone Minima
 * @docs docs/monotone-minima.md
 */
template<typename T, typename Compare = less<T> >
vector<pair<int, T> > monotone_minima(int H, int W, const function<T(int, int)> &f, const Compare &comp = Compare()) {
  vector<pair<int, T> > dp(H);
  function<void(int, int, int, int)> dfs = [&](int top, int bottom, int left, int right) {
    if (top > bottom) return;
    int line = (top + bottom) / 2;
    T ma;
    int mi = -1;
    for (int i = left; i <= right; i++) {
      T cst = f(line, i);
      if (mi == -1 || comp(cst, ma)) {
        ma = cst;
        mi = i;
      }
    }
    dp[line] = make_pair(mi, ma);
    dfs(top, line - 1, left, mi);
    dfs(line + 1, bottom, mi, right);
  };
  dfs(0, H - 1, 0, W - 1);
  return dp;
}

#line 2 "dp/online-offline-dp.cpp"

/**
 * @brief  Online Offline DP(オンライン・オフライン変換)
 * @docs docs/online-offline-dp.md
 */
template<typename T, typename Compare = less<T> >
vector<T> online_offline_dp(int W, const function<T(int, int)> &f, const Compare &comp = Compare()) {
  vector<T> dp(W + 1);
  vector<int> isset(W + 1);
  int y_base = -1, x_base = -1;
  function<T(int, int)> get_cost = [&](int y, int x) { // return dp[0, x+x_base)+f[x+x_base, y+y_base)
    return dp[x + x_base] + f(x + x_base, y + y_base);
  };
  function<void(int, int, int)> induce = [&](int l, int m, int r) { // dp[l, m) -> dp[m, r)
    x_base = l, y_base = m;
    auto ret = monotone_minima(r - m, m - l, get_cost, comp);
    for (int i = 0; i < ret.size(); i++) {
      if (!isset[m + i] || comp(ret[i].second, dp[m + i])) {
        isset[m + i] = true;
        dp[m + i] = ret[i].second;
      }
    }
  };
  function<void(int, int)> dfs = [&](int l, int r) {
    if (l + 1 == r) {
      x_base = l, y_base = l;
      T cst = l ? get_cost(0, -1) : 0;
      if (!isset[l] || comp(cst, dp[l])) {
        isset[l] = true;
        dp[l] = cst;
      }
    } else {
      int mid = (l + r) / 2;
      dfs(l, mid);
      induce(l, mid, r);
      dfs(mid, r);
    }
  };
  dfs(0, W + 1);
  return dp;
};

/**
 * @brief Sparse-Table(スパーステーブル)
 * @docs docs/sparse-table.md
 */
template<typename T, typename F>
struct SparseTable {
  F f;
  vector<vector<T> > st;
  vector<int> lookup;

  SparseTable() = default;

  explicit SparseTable(const vector<T> &v, const F &f) : f(f) {
    const int n = (int) v.size();
    const int b = 32 - __builtin_clz(n);
    st.assign(b, vector<T>(n));
    for (int i = 0; i < v.size(); i++) {
      st[0][i] = v[i];
    }
    for (int i = 1; i < b; i++) {
      for (int j = 0; j + (1 << i) <= n; j++) {
        st[i][j] = f(st[i - 1][j], st[i - 1][j + (1 << (i - 1))]);
      }
    }
    lookup.resize(v.size() + 1);
    for (int i = 2; i < lookup.size(); i++) {
      lookup[i] = lookup[i >> 1] + 1;
    }
  }

  inline T fold(int l, int r) const {
    int b = lookup[r - l];
    return f(st[b][l], st[b][r - (1 << b)]);
  }
};

template<typename T, typename F>
SparseTable<T, F> get_sparse_table(const vector<T> &v, const F &f) {
  return SparseTable<T, F>(v, f);
}


int main() {
  int n, l;
  cin >> n >> l;
  vector<int> A(n);
  for (auto &a : A) cin >> a;
  auto rmq = get_sparse_table(A, [&](int a, int b) { return max(a, b); });
  function<int64_t(int, int)> dist = [&](int i, int j) -> int64_t {
    assert(0 <= i && i < j && j <= n);
    if (j - i < l) return -infll+1LL*inf*(j-i);
    else return rmq.fold(i, j);
  };
  cout << online_offline_dp(n, dist, greater<>()).back() << endl;
}
accuracy: 1
time_ms: 90
memory_kb: 18944
final_rank: 16

code_snippet: #line 1 "larsch.test.cpp"
#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/challenges/search/titles/3086"
#include <iostream>
#line 2 "/Users/kodamankod/Desktop/CppProcon/Library/proconlib/algorithm/larsch.cpp"
#include <cassert>
#include <functional>
#include <memory>
#include <vector>
#line 2 "/Users/kodamankod/Desktop/CppProcon/Library/proconlib/utility/int_alias.cpp"
#include <cstddef>
#include <cstdint>

using i32 = std::int32_t;
using u32 = std::uint32_t;
using i64 = std::int64_t;
using u64 = std::uint64_t;
using isize = std::ptrdiff_t;
using usize = std::size_t;
#line 7 "/Users/kodamankod/Desktop/CppProcon/Library/proconlib/algorithm/larsch.cpp"

class LARSCH {
    using Select = std::function<bool(usize, usize, usize)>;
    struct ReduceRow;
    struct ReduceCol;

    struct ReduceRow {
        usize n, m, x, k;
        Select f;
        std::unique_ptr<ReduceCol> rec;

        explicit ReduceRow(const usize n_, const Select& f_) : n(n_), m(0), x(0), k(0), f(f_), rec() {
            const usize h = n / 2;
            if (h != 0)
                rec = std::make_unique<ReduceCol>(h, [&](usize i, usize j, usize k) { return f(2 * i + 1, j, k); });
        }

        void add_column() {
            if ((x & 1) and f(x, k, m)) k = m;
            if (rec) rec->add_column();
            m += 1;
        }

        usize get_argmin() {
            if (x & 1) {
                x += 1;
                return k;
            } else {
                usize ret = k;
                if (x + 1 == n)
                    k = m - 1;
                else
                    k = rec->get_argmin();
                for (usize j = ret + 1; j <= k; j += 1)
                    if (f(x, ret, j)) ret = j;
                x += 1;
                return ret;
            }
        }
    };

    struct ReduceCol {
        usize n, m, x, y;
        std::vector<usize> c;
        Select f;
        ReduceRow rec;

        explicit ReduceCol(const usize n_, const Select& f_)
            : n(n_), m(0), x(0), y(0), c(), f(f_), rec(n_, [&](usize i, usize j, usize k) { return f(i, c[j], c[k]); }) {}

        void add_column() {
            if (x == n) return;
            while (true) {
                const usize i = c.size();
                if (i <= x or !f(i - 1, c[i - 1], m)) break;
                c.pop_back();
            }
            if (c.size() != n) c.push_back(m);
            m += 1;
        }

        usize get_argmin() {
            x += 1;
            while (y < std::min(x, c.size())) {
                rec.add_column();
                y += 1;
            }
            return c[rec.get_argmin()];
        }
    };

    usize row, col;
    ReduceRow machine;

  public:
    explicit LARSCH(const usize n, const Select& f) : row(n), col(0), machine(n, f) {}

    void add_column() {
        assert(row != 0);
        col += 1;
        machine.add_column();
    }

    usize get_argmin() {
        assert(row != 0 and col != 0);
        row -= 1;
        return machine.get_argmin();
    }
};

template <class T, class Comp = std::less<T>> class CompLARSCH {
    std::function<T(usize, usize)> func;
    Comp comp;
    LARSCH machine;

  public:
    explicit CompLARSCH(const usize n, const std::function<T(usize, usize)>& f, const Comp& c = Comp())
        : func(f), comp(c), machine(n, [&](usize i, usize j, usize k) { return comp(func(i, k), func(i, j)); }) {}

    void add_column() { machine.add_column(); }

    usize get_argmin() { return machine.get_argmin(); }
};
#line 3 "/Users/kodamankod/Desktop/CppProcon/Library/proconlib/traits/max_monoid.cpp"
#include <limits>

template <class T> struct MaxMonoid {
    using Type = T;
    static constexpr T identity() { return std::numeric_limits<T>::min(); }
    static constexpr T operation(const T& l, const T& r) { return std::max(l, r); }
};
#line 3 "/Users/kodamankod/Desktop/CppProcon/Library/proconlib/bit/ceil_log2.cpp"

__attribute__((target("avx2"))) constexpr u64 ceil_log2(const u64 x) {
    u64 e = 0;
    while (((u64)1 << e) < x) ++e;
    return e;
}
#line 2 "/Users/kodamankod/Desktop/CppProcon/Library/proconlib/utility/rep.cpp"
#include <algorithm>
#line 4 "/Users/kodamankod/Desktop/CppProcon/Library/proconlib/utility/rep.cpp"

class rep {
    struct Iter {
        usize itr;
        constexpr Iter(const usize pos) noexcept : itr(pos) {}
        constexpr void operator++() noexcept { ++itr; }
        constexpr bool operator!=(const Iter& other) const noexcept { return itr != other.itr; }
        constexpr usize operator*() const noexcept { return itr; }
    };
    const Iter first, last;

  public:
    explicit constexpr rep(const usize first, const usize last) noexcept : first(first), last(std::max(first, last)) {}
    constexpr Iter begin() const noexcept { return first; }
    constexpr Iter end() const noexcept { return last; }
};
#line 4 "/Users/kodamankod/Desktop/CppProcon/Library/proconlib/utility/revrep.cpp"

class revrep {
    struct Iter {
        usize itr;
        constexpr Iter(const usize pos) noexcept : itr(pos) {}
        constexpr void operator++() noexcept { --itr; }
        constexpr bool operator!=(const Iter& other) const noexcept { return itr != other.itr; }
        constexpr usize operator*() const noexcept { return itr; }
    };
    const Iter first, last;

  public:
    explicit constexpr revrep(const usize first, const usize last) noexcept
        : first(last - 1), last(std::min(first, last) - 1) {}
    constexpr Iter begin() const noexcept { return first; }
    constexpr Iter end() const noexcept { return last; }
};
#line 8 "/Users/kodamankod/Desktop/CppProcon/Library/proconlib/container/segment_tree.cpp"

template <class M> class SegmentTree {
    using T = typename M::Type;
    usize internal_size, seg_size;
    std::vector<T> data;

    void fetch(const usize k) { data[k] = M::operation(data[2 * k], data[2 * k + 1]); }

  public:
    explicit SegmentTree(const usize size = 0, const T& value = M::identity())
        : SegmentTree(std::vector<T>(size, value)) {}
    explicit SegmentTree(const std::vector<T>& vec) : internal_size(vec.size()) {
        seg_size = 1 << ceil_log2(internal_size);
        data = std::vector<T>(2 * seg_size, M::identity());
        for (const usize i : rep(0, internal_size)) data[seg_size + i] = vec[i];
        for (const usize i : revrep(1, seg_size)) fetch(i);
    }

    usize size() const { return internal_size; }

    void assign(usize i, const T& value) {
        assert(i < internal_size);
        i += seg_size;
        data[i] = value;
        while (i > 1) {
            i >>= 1;
            fetch(i);
        }
    }

    T fold() const { return data[1]; }
    T fold(usize l, usize r) const {
        assert(l <= r and r <= internal_size);
        l += seg_size;
        r += seg_size;
        T ret_l = M::identity(), ret_r = M::identity();
        while (l < r) {
            if (l & 1) ret_l = M::operation(ret_l, data[l++]);
            if (r & 1) ret_r = M::operation(data[--r], ret_r);
            l >>= 1;
            r >>= 1;
        }
        return M::operation(ret_l, ret_r);
    }

    template <class F> usize max_right(usize l, const F& f) const {
        assert(l <= internal_size);
        assert(f(M::identity()));
        if (l == internal_size) return internal_size;
        l += seg_size;
        T sum = M::identity();
        do {
            while (!(l & 1)) l >>= 1;
            if (!f(M::operation(sum, data[l]))) {
                while (l < seg_size) {
                    l = 2 * l;
                    if (f(M::operation(sum, data[l]))) sum = M::operation(sum, data[l++]);
                }
                return l - seg_size;
            }
            sum = M::operation(sum, data[l++]);
        } while ((l & -l) != l);
        return internal_size;
    }

    template <class F> usize min_left(usize r, const F& f) const {
        assert(r <= internal_size);
        assert(f(M::identity()));
        if (r == 0) return 0;
        r += seg_size;
        T sum = M::identity();
        do {
            r -= 1;
            while (r > 1 and (r & 1)) r >>= 1;
            if (!f(M::operation(data[r], sum))) {
                while (r < seg_size) {
                    r = 2 * r + 1;
                    if (f(M::operation(data[r], sum))) sum = M::operation(data[r--], sum);
                }
                return r + 1 - seg_size;
            }
            sum = M::operation(data[r], sum);
        } while ((r & -r) != r);
        return 0;
    }
};
#line 3 "/Users/kodamankod/Desktop/CppProcon/Library/proconlib/utility/infty.cpp"

template <class T, T Div = 2> constexpr T INFTY = std::numeric_limits<T>::max() / Div;
#line 10 "larsch.test.cpp"

int main() {
    usize N, L;
    std::cin >> N >> L;
    std::vector<i64> A(N);
    for (auto& x : A) {
        std::cin >> x;
    }
    SegmentTree<MaxMonoid<i64>> seg(A);
    std::vector<i64> dp(N + 1);
    const auto transit = [&](usize i, const usize j) {
        i += 1;
        if (j + L > i) return -INFTY<i64>;
        return dp[j] + seg.fold(j, i);
    };
    CompLARSCH<i64, std::greater<i64>> larsch(N, transit);
    for (const auto i : rep(0, N)) {
        larsch.add_column();
        dp[i + 1] = transit(i, larsch.get_argmin());
    }
    std::cout << dp[N] << '\n';
    return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 11372
final_rank: 11

code_snippet: #include <utility>
#include <vector>

template <class C, class T = decltype(std::declval<C>().get())>
T incremental_monge_shortest_path(const int n, C init) {
  class env {
  public:
    C mid;
    C last;
    int prev;
  };
  std::vector<env> nodes;
  {
    int n_ = n;
    int d = 0;
    while (n_ != 0) {
      n_ /= 2;
      d += 1;
    }
    nodes.assign(d, {init, init, 0});
  }
  std::vector<T> dp(n + 1, static_cast<T>(0));

  const auto f = [&](const auto &f, const int d, const int r) -> int {
    auto &[mid, last, prev] = nodes[d];
    const int w = 1 << d;
    if ((r >> d) % 2 == 1) {
      for (int i = std::max(0, r - 2 * w); i != r; i += 1) {
        mid.push_back(i);
      }
      const int next = r + w <= n ? f(f, d + 1, r + w) : r - w;
      int argmin = prev;
      dp[r] = dp[argmin] + mid.get();
      for (int i = prev; i != next;) {
        mid.pop_front(i);
        i += 1;
        const T t = dp[i] + mid.get();
        if (dp[r] > t) {
          dp[r] = t;
          argmin = i;
        }
      }
      prev = next;
      return argmin;
    } else {
      for (int i = std::max(0, r - 2 * w); i != r; i += 1) {
        last.push_back(i);
      }
      for (int i = std::max(0, r - 3 * w); i != r - 2 * w; i += 1) {
        last.pop_front(i);
      }
      int argmin = prev;
      for (int i = r - 2 * w; i != r - w;) {
        last.pop_front(i);
        i += 1;
        const T t = dp[i] + last.get();
        if (dp[r] > t) {
          dp[r] = t;
          argmin = i;
        }
      }
      return argmin;
    }
  };

  for (int i = 1; i != n + 1; i += 1) {
    f(f, 0, i);
  }

  return dp[n];
}

#include <algorithm>
#include <iostream>
#include <vector>

#include <cassert>

int main() {
  using i64 = long long;
  static constexpr i64 INF = 1e11;

  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);

  int N, L;
  std::cin >> N >> L;
  std::vector<i64> a(N);
  for (i64 &e : a) {
    std::cin >> e;
    e = -e;
  }

  struct queue {
    const std::vector<i64> *a;
    const int *L;
    std::vector<i64> front;
    i64 rear;
    int l, r;

    void pop_front(int) {
      if (front.empty()) {
        rear = INF;
        front.clear();
        i64 t = INF;
        for (int i = r; i != l;) {
          i -= 1;
          t = std::min(t, (*a)[i]);
          front.push_back(t);
        }
      }
      front.pop_back();
      l += 1;
    }

    void push_back(int) {
      rear = std::min(rear, (*a)[r]);
      r += 1;
    }

    i64 get() {
      if (r - l < *L) {
        return INF;
      } else {
        return std::min(front.empty() ? INF : front.back(), rear);
      }
    }
  };

  const i64 ans =
      incremental_monge_shortest_path(N, queue({&a, &L, {}, INF, 0, 0}));

  std::cout << -ans << "\n";

  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 22664
final_rank: 18

code_snippet: #include <utility>
#include <vector>

template <class C, class T = decltype(std::declval<C>().get())>
T incremental_monge_shortest_path(const int n, C init) {
  class env {
  public:
    C mid;
    C last;
    int prev;
  };
  std::vector<env> nodes;
  {
    int n_ = n;
    int d = 0;
    while (n_ != 0) {
      n_ /= 2;
      d += 1;
    }
    nodes.assign(d, {init, init, 0});
  }
  std::vector<T> dp(n + 1, static_cast<T>(0));

  const auto f = [&](const auto &f, const int d, const int r) -> int {
    auto &[mid, last, prev] = nodes[d];
    const int w = 1 << d;
    if ((r >> d) % 2 == 1) {
      for (int i = std::max(0, r - 2 * w); i != r; i += 1) {
        mid.push_back(i);
      }
      const int next = r + w <= n ? f(f, d + 1, r + w) : r - w;
      int argmin = prev;
      dp[r] = dp[argmin] + mid.get();
      for (int i = prev; i != next;) {
        mid.pop_front(i);
        i += 1;
        const T t = dp[i] + mid.get();
        if (dp[r] > t) {
          dp[r] = t;
          argmin = i;
        }
      }
      prev = next;
      return argmin;
    } else {
      for (int i = std::max(0, r - 2 * w); i != r; i += 1) {
        last.push_back(i);
      }
      for (int i = std::max(0, r - 3 * w); i != r - 2 * w; i += 1) {
        last.pop_front(i);
      }
      int argmin = prev;
      for (int i = r - 2 * w; i != r - w;) {
        last.pop_front(i);
        i += 1;
        const T t = dp[i] + last.get();
        if (dp[r] > t) {
          dp[r] = t;
          argmin = i;
        }
      }
      return argmin;
    }
  };

  for (int i = 1; i != n + 1; i += 1) {
    f(f, 0, i);
  }

  return dp[n];
}

#include <algorithm>
#include <iostream>
#include <vector>

#include <cassert>

int main() {
  using i64 = long long;
  static constexpr i64 INF = 1e11;

  int N, L;
  std::cin >> N >> L;
  std::vector<i64> a(N);
  for (i64 &e : a) {
    std::cin >> e;
    e = -e;
  }

  struct queue {
    const std::vector<i64> *a;
    const int *L;
    std::vector<i64> front;
    i64 rear;
    int l, r;

    void pop_front(int) {
      if (front.empty()) {
        rear = INF;
        front.clear();
        i64 t = INF;
        for (int i = r; i != l;) {
          i -= 1;
          t = std::min(t, (*a)[i]);
          front.push_back(t);
        }
      }
      front.pop_back();
      l += 1;
    }

    void push_back(int) {
      rear = std::min(rear, (*a)[r]);
      r += 1;
    }

    i64 get() {
      if (r - l < *L) {
        return INF;
      } else {
        return std::min(front.empty() ? INF : front.back(), rear);
      }
    }
  };

  const i64 ans =
      incremental_monge_shortest_path(N, queue({&a, &L, {}, INF, 0, 0}));

  std::cout << -ans << "\n";

  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 22748
final_rank: 20

code_snippet: #include <utility>
#include <vector>

template <class C, class T = decltype(std::declval<C>().get())>
T incremental_monge_shortest_path(const int n, C init) {
  class env {
  public:
    C mid;
    C last;
    int prev;
  };
  std::vector<env> nodes;
  {
    int n_ = n;
    int d = 0;
    while (n_ != 0) {
      n_ /= 2;
      d += 1;
    }
    nodes.assign(d, {init, init, 0});
  }
  std::vector<T> dp(n + 1, static_cast<T>(0));

  const auto f = [&](const auto &f, const int d, const int r) -> int {
    auto &[mid, last, prev] = nodes[d];
    const int w = 1 << d;
    if ((r >> d) % 2 == 1) {
      for (int i = std::max(0, r - 2 * w); i != r; i += 1) {
        mid.push_back(i);
      }
      const int next = r + w <= n ? f(f, d + 1, r + w) : r - w;
      int argmin = prev;
      dp[r] = dp[argmin] + mid.get();
      for (int i = prev; i != next;) {
        mid.pop_front(i);
        i += 1;
        const T t = dp[i] + mid.get();
        if (dp[r] > t) {
          dp[r] = t;
          argmin = i;
        }
      }
      prev = next;
      return argmin;
    } else {
      for (int i = std::max(0, r - 2 * w); i != r; i += 1) {
        last.push_back(i);
      }
      for (int i = std::max(0, r - 3 * w); i != r - 2 * w; i += 1) {
        last.pop_front(i);
      }
      int argmin = prev;
      for (int i = r - 2 * w; i != r - w;) {
        last.pop_front(i);
        i += 1;
        const T t = dp[i] + last.get();
        if (dp[r] > t) {
          dp[r] = t;
          argmin = i;
        }
      }
      return argmin;
    }
  };

  for (int i = 1; i != n + 1; i += 1) {
    f(f, 0, i);
  }

  return dp[n];
}

#include <algorithm>
#include <iostream>
#include <vector>

#include <cassert>

int main() {
  using i64 = long long;
  static constexpr i64 INF = 1e11;

  int N, L;
  std::cin >> N >> L;
  std::vector<i64> a(N);
  for (i64 &e : a) {
    std::cin >> e;
    e = -e;
  }

  struct queue {
    const std::vector<i64> *a;
    const int *L;
    std::vector<i64> front;
    i64 rear;
    int l, r;

    void pop_front(int l_) {
      assert(l == l_);
      if (front.empty()) {
        rear = INF;
        front.clear();
        i64 t = INF;
        for (int i = r; i != l;) {
          i -= 1;
          t = std::min(t, (*a)[i]);
          front.push_back(t);
        }
      }
      front.pop_back();
      l += 1;
    }

    void push_back(int r_) {
      assert(r == r_);
      rear = std::min(rear, (*a)[r]);
      r += 1;
    }

    i64 get() {
      i64 v;
      if (r - l < *L) {
        v = INF;
      } else {
        v = std::min(front.empty() ? INF : front.back(), rear);
      }
      // std::cout << l << " " << r << " " << v << "\n";
      return v;
    }
  };

  const i64 ans =
      incremental_monge_shortest_path(N, queue({&a, &L, {}, INF, 0, 0}));

  std::cout << -ans << "\n";

  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 22588
final_rank: 19

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 200005

struct Info{
	Info(int arg_start_index,ll arg_value){
		start_index = arg_start_index;
		value = arg_value;
	}
	int start_index;
	ll value;
};

int N,L;
ll max_data[6*SIZE],add_data[6*SIZE];
ll A[SIZE];

void init(ll first_N){
	N = 1;
	while(N < first_N)N *= 2;
}

void add(int left,int right,ll value,int node_id,int node_left,int node_right){

	if(right < node_left || left > node_right){
		//範囲外ならreturn
		return;
	}
	else if(left <= node_left && right >= node_right){ //このノードのカバーしている区間が、更新区間の部分区間である場合

		add_data[node_id] += value; //一様に加える値を加算

		while(node_id != 0){

			node_id = (node_id-1)/2; //下から上に向かって、最小値および最大値更新
			max_data[node_id] = max(max_data[2*node_id+1]+add_data[2*node_id+1],max_data[2*node_id+2]+add_data[2*node_id+2]);
		}
	}else{

		add(left,right,value,2*node_id+1,node_left,(node_left+node_right)/2);
		add(left,right,value,2*node_id+2,(node_left+node_right)/2+1,node_right);
	}
}


ll getMax(int left,int right,int node_id,int node_left,int node_right){
	if(right < node_left || left > node_right)return -HUGE_NUM;
	else if(left <= node_left && right >= node_right){
		return max_data[node_id]+add_data[node_id];

	}else{

		ll  left_max  = getMax(left,right,2*node_id+1,node_left,(node_left+node_right)/2);
		ll  right_max = getMax(left,right,2*node_id+2,(node_left+node_right)/2+1,node_right);
		return max(left_max,right_max)+add_data[node_id];
	}
}

int main(){

	int first_N;
	scanf("%d %d",&first_N,&L);

	for(ll i = 0; i < first_N; i++){

		scanf("%lld",&A[i]);
	}

	init(first_N);

	for(int i = 0; i <= 2*N-2; i++){
		max_data[i] = 0;
		add_data[i] = 0;
	}


	stack<Info> S; //Info(基準点,それ以右の最大値)

	//dp[i] := iまでの最大値+(i+1より右の最大値)

	ll maxi = -HUGE_NUM;

	for(int i = 0; i < first_N; i++){

		ll a = A[i];
		maxi = max(maxi,a);

		//以右最大値の更新
		int right = i-1;

		//printf("i:%d a:%lld maxi:%lld\n",i,a,maxi);

		int last = -1;

		while(!S.empty() && S.top().value <= a){

			ll diff = a-S.top().value;
			//printf("%lldを%d-%dに加算\n",diff,S.top().start_index,right);
			add(S.top().start_index,right,diff,0,0,N-1);

			last = S.top().start_index;
			right = S.top().start_index-1;

			S.pop();
		}

		if(last != -1){

			S.push(Info(last,a));
		}

		S.push(Info(i,0));

		if(i < L){ //左に区間なし

			if(i < L-1){

				add(i,i,-HUGE_NUM,0,0,N-1); //全ての区間長がL以上でなければならない

			}else{

				add(i,i,maxi,0,0,N-1);
			}

		}else{

			ll tmp = getMax(0,i-L,0,0,N-1);
			//printf("tmp:%lld\n",tmp);
			add(i,i,max(tmp,maxi),0,0,N-1);
		}
	}

	printf("%lld\n",getMax(first_N-1,first_N-1,0,0,N-1));

	return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 14656
final_rank: 14

code_snippet: // #line 1 "test/larsch.test.cpp"
#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=3086"

// #line 2 "other/int_alias.cpp"

#include <cstddef>
#include <cstdint>

using i32 = std::int32_t;
using i64 = std::int64_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;
using isize = std::ptrdiff_t;
using usize = std::size_t;
#include <functional>
#include <memory>
#include <vector>

template <class T> class larsch {
  struct reduce_row;
  struct reduce_col;

  struct reduce_row {
    int n;
    std::function<T(int, int)> f;
    int cur_row;
    int state;
    std::unique_ptr<reduce_col> rec;

    reduce_row(int n_) : n(n_), f(), cur_row(0), state(0), rec() {
      const int m = n / 2;
      if (m != 0) {
        rec = std::make_unique<reduce_col>(m);
      }
    }

    void set_f(std::function<T(int, int)> f_) {
      f = f_;
      if (rec) {
        rec->set_f([&](int i, int j) -> T { return f(2 * i + 1, j); });
      }
    }

    int get_argmin() {
      const int cur_row_ = cur_row;
      cur_row += 1;
      if (cur_row_ % 2 == 0) {
        const int prev_argmin = state;
        const int next_argmin = [&]() {
          if (cur_row_ + 1 == n) {
            return n - 1;
          } else {
            return rec->get_argmin();
          }
        }();
        state = next_argmin;
        int ret = prev_argmin;
        for (int j = prev_argmin + 1; j <= next_argmin; j += 1) {
          if (f(cur_row_, ret) > f(cur_row_, j)) {
            ret = j;
          }
        }
        return ret;
      } else {
        if (f(cur_row_, state) <= f(cur_row_, cur_row_)) {
          return state;
        } else {
          return cur_row_;
        }
      }
    }
  };

  struct reduce_col {
    int n;
    std::function<T(int, int)> f;
    int cur_row;
    std::vector<int> cols;
    reduce_row rec;

    reduce_col(int n_) : n(n_), f(), cur_row(0), cols(), rec(n) {}

    void set_f(std::function<T(int, int)> f_) {
      f = f_;
      rec.set_f([&](int i, int j) -> T { return f(i, cols[j]); });
    }

    int get_argmin() {
      const int cur_row_ = cur_row;
      cur_row += 1;
      const auto cs = [&]() -> std::vector<int> {
        if (cur_row_ == 0) {
          return {{0}};
        } else {
          return {{2 * cur_row_ - 1, 2 * cur_row_}};
        }
      }();
      for (const int j : cs) {
        while ([&]() {
          const int size = cols.size();
          return size != cur_row_ && f(size - 1, cols.back()) > f(size - 1, j);
        }()) {
          cols.pop_back();
        }
        if (cols.size() != n) {
          cols.push_back(j);
        }
      }
      return cols[rec.get_argmin()];
    }
  };

  std::unique_ptr<reduce_row> base;

public:
  larsch(int n, std::function<T(int, int)> f)
      : base(std::make_unique<reduce_row>(n)) {
    base->set_f(f);
  }

  int get_argmin() { return base->get_argmin(); }
};

/**
 * @brief LARSCH Algorithm
 * @docs docs/larsch.md
 */
// #line 2 "data_structure/segment_tree.cpp"

#include <cassert>
// #line 6 "data_structure/segment_tree.cpp"

template <class M> class segment_tree {
  using T = typename M::value_type;

public:
  using value_type = T;

private:
  std::vector<T> tree;

  template <class F>
  usize search_subtree(usize index, const F f, T fold_l) const {
    while (index < size()) {
      const T temp = M::operation(fold_l, tree[index * 2]);
      if (!f(temp)) {
        index = index * 2;
      } else {
        fold_l = temp;
        index = index * 2 + 1;
      }
    }
    return index - size();
  }

public:
  segment_tree() = default;

  explicit segment_tree(const usize n) : tree(n * 2, M::identity) {}

  usize size() const noexcept { return tree.size() / 2; }

  T fold(usize first, usize last) const {
    assert(first <= last);
    assert(last <= size());
    first += size();
    last += size();
    T fold_l = M::identity;
    T fold_r = M::identity;
    while (first != last) {
      if (first % 2 != 0) {
        fold_l = M::operation(fold_l, tree[first]);
        first += 1;
      }
      first /= 2;
      if (last % 2 != 0) {
        last -= 1;
        fold_r = M::operation(tree[last], fold_r);
      }
      last /= 2;
    }
    return M::operation(fold_l, fold_r);
  }

  template <class F> usize search(usize first, usize last, const F f) const {
    assert(first <= last);
    assert(last <= size());
    first += size();
    last += size();
    const usize last_cp = last;
    usize shift = 0;
    T fold_l = M::identity;
    while (first != last) {
      if (first % 2 != 0) {
        const T temp = M::operation(fold_l, tree[first]);
        if (!f(temp))
          return search_subtree(first, f, fold_l);
        fold_l = temp;
        first += 1;
      }
      first /= 2;
      last /= 2;
      shift += 1;
    }
    while (shift != 0) {
      shift -= 1;
      last = last_cp >> shift;
      if (last % 2 != 0) {
        last -= 1;
        const T temp = M::operation(fold_l, tree[last]);
        if (!f(temp))
          return search_subtree(last, f, fold_l);
        fold_l = temp;
      }
    }
    return last_cp - size();
  }

  void update(usize index, const T x) {
    assert(index < size());
    index += size();
    tree[index] = x;
    while (index != 1) {
      index /= 2;
      tree[index] = M::operation(tree[index * 2], tree[index * 2 + 1]);
    }
  }
};

/**
 * @brief Segment Tree
 * @docs docs/segment_tree.md
 * @see https://scrapbox.io/data-structures/Segment_Tree
 */
// #line 1 "other/less_equal_ordered_set.cpp"
template <class T> class less_equal_ordered_set {
public:
  using value_type = T;
  static constexpr bool compare(const T &x, const T &y) noexcept {
    return x <= y;
  }
};
// #line 1 "other/min_semigroup.cpp"
template <class W> class min_semigroup {
  using T = typename W::value_type;

public:
  using value_type = T;
  static constexpr T operation(const T &l, const T &r) noexcept {
    return W::compare(l, r) ? l : r;
  }
};
// #line 1 "other/opposite_ordered_set.cpp"
template <class W> class opposite_ordered_set {
  using T = typename W::value_type;

public:
  using value_type = T;
  static constexpr bool compare(const T &l, const T &r) noexcept {
    return W::compare(r, l);
  }
};
// #line 1 "other/semigroup_to_monoid.cpp"
#include <optional>
#include <utility>

template <class S> class semigroup_to_monoid {
  using T = std::optional<typename S::value_type>;

public:
  using value_type = T;
  static constexpr T operation(const T &l, const T &r) noexcept {
    if (!l)
      return r;
    if (!r)
      return l;
    return T(std::in_place, S::operation(*l, *r));
  }
  static constexpr T identity{std::nullopt};
};
// #line 10 "test/larsch.test.cpp"

#include <iostream>
#include <limits>

int main() {
  // #line 1 "other/fast_ios.cpp"
  std::ios::sync_with_stdio(false);
  std::cin.tie(nullptr);
  // #line 16 "test/larsch.test.cpp"

  static constexpr i64 inf = std::numeric_limits<i64>::max() / 2;

  usize n, l;
  std::cin >> n >> l;

  segment_tree<semigroup_to_monoid<
      min_semigroup<opposite_ordered_set<less_equal_ordered_set<i64>>>>>
      seg(n);
  for (usize i = 0; i != n; ++i) {
    i64 a;
    std::cin >> a;
    seg.update(i, a);
  }

  std::vector<i64> dp(n + 1);
  dp[0] = 0;

  const auto f = [&](const usize to_, const usize from) -> i64 {
    const usize to = to_ + 1;
    if (to - from < l) {
      return -inf;
    } else {
      return dp[from] + *seg.fold(from, to);
    }
  };

  larsch<i64> larsch_(n, [&](int i, int j) { return -f(i, j); });
  for (usize i = 0; i != n; i += 1) {
    dp[i + 1] = f(i, larsch_.get_argmin());
  }

  std::cout << dp[n] << "\n";

  return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 10112
final_rank: 9

code_snippet: #line 1 "test/larsch.test.cpp"
#define PROBLEM "http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=3086"

#line 2 "other/int_alias.cpp"

#include <cstddef>
#include <cstdint>

using i32 = std::int32_t;
using i64 = std::int64_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;
using isize = std::ptrdiff_t;
using usize = std::size_t;
#line 2 "algorithm/larsch.cpp"

#include <vector>

template <class Select, class Update>
void larsch(const std::size_t n, Select select, Update update) {
  using usize = std::size_t;

  class header {
  public:
    usize r;
    usize c;
  };

  class node {
  public:
    std::vector<usize> cols;
    usize prev;

    std::vector<header> tent;
    usize pcnt;
    usize curc;

    node(const usize n) : cols(), prev(0), tent(), pcnt(0), curc(0) {
      cols.reserve(n);
      tent.reserve(n / 2);
    }
  };

  std::vector<node> data;

  {
    usize m = n;
    while (m != 0) {
      data.emplace_back(m);
      m /= 2;
    }
  }

  const auto act = [&](const auto &act, const usize layer,
                       const usize row) -> usize {
    node &t = data[layer];

    if ((row >> layer) % 2 == 0) {
      usize res = t.prev;
      usize idx = t.curc;
      while (idx != t.cols.size()) {
        if (select(row, t.cols[res], t.cols[idx])) {
          res = idx;
        }
        idx += 1;
      }
      t.prev = res;
      return t.cols[res];
    }

    const usize a = [&]() {
      const usize step = static_cast<usize>(1) << layer;
      if (row + step > n) {
        return t.cols.back();
      }
      while (t.curc != t.cols.size()) {
        const usize c = t.cols[t.curc];
        while (t.tent.size() != t.pcnt &&
               select(t.tent.back().r, t.tent.back().c, c)) {
          t.tent.pop_back();
        }
        if (t.tent.size() == t.pcnt) {
          t.tent.push_back({row + step, c});
        } else if (t.tent.back().r + step * 2 <= n) {
          t.tent.push_back({t.tent.back().r + step * 2, c});
        }
        t.curc += 1;
      }
      if (t.pcnt != t.tent.size()) {
        data[layer + 1].cols.push_back(t.tent[t.pcnt].c);
        t.pcnt += 1;
      }
      return act(act, layer + 1, row + step);
    }();

    usize res = t.prev;
    usize idx = t.prev;
    while (t.cols[idx] != a) {
      idx += 1;
      if (select(row, t.cols[res], t.cols[idx])) {
        res = idx;
      }
    }
    t.prev = idx;
    return t.cols[res];
  };

  for (usize i = 0; i != n;) {
    data[0].cols.push_back(i);
    i += 1;
    update(i, act(act, 0, i));
  }
}

/**
 * @brief LARSCH Algorithm
 * @docs docs/larsch.md
 */
#line 2 "data_structure/segment_tree.cpp"

#include <cassert>
#line 6 "data_structure/segment_tree.cpp"

template <class M> class segment_tree {
  using T = typename M::value_type;

public:
  using value_type = T;

private:
  std::vector<T> tree;

  template <class F>
  usize search_subtree(usize index, const F f, T fold_l) const {
    while (index < size()) {
      const T temp = M::operation(fold_l, tree[index * 2]);
      if (!f(temp)) {
        index = index * 2;
      } else {
        fold_l = temp;
        index = index * 2 + 1;
      }
    }
    return index - size();
  }

public:
  segment_tree() = default;

  explicit segment_tree(const usize n) : tree(n * 2, M::identity) {}

  usize size() const noexcept { return tree.size() / 2; }

  T fold(usize first, usize last) const {
    assert(first <= last);
    assert(last <= size());
    first += size();
    last += size();
    T fold_l = M::identity;
    T fold_r = M::identity;
    while (first != last) {
      if (first % 2 != 0) {
        fold_l = M::operation(fold_l, tree[first]);
        first += 1;
      }
      first /= 2;
      if (last % 2 != 0) {
        last -= 1;
        fold_r = M::operation(tree[last], fold_r);
      }
      last /= 2;
    }
    return M::operation(fold_l, fold_r);
  }
  
  template <class F> usize search(usize first, usize last, const F f) const {
    assert(first <= last);
    assert(last <= size());
    first += size();
    last += size();
    const usize last_cp = last;
    usize shift = 0;
    T fold_l = M::identity;
    while (first != last) {
      if (first % 2 != 0) {
        const T temp = M::operation(fold_l, tree[first]);
        if (!f(temp))
          return search_subtree(first, f, fold_l);
        fold_l = temp;
        first += 1;
      }
      first /= 2;
      last /= 2;
      shift += 1;
    }
    while (shift != 0) {
      shift -= 1;
      last = last_cp >> shift;
      if (last % 2 != 0) {
        last -= 1;
        const T temp = M::operation(fold_l, tree[last]);
        if (!f(temp))
          return search_subtree(last, f, fold_l);
        fold_l = temp;
      }
    }
    return last_cp - size();
  }

  void update(usize index, const T x) {
    assert(index < size());
    index += size();
    tree[index] = x;
    while (index != 1) {
      index /= 2;
      tree[index] = M::operation(tree[index * 2], tree[index * 2 + 1]);
    }
  }
};

/**
 * @brief Segment Tree
 * @docs docs/segment_tree.md
 * @see https://scrapbox.io/data-structures/Segment_Tree
 */
#line 1 "other/less_equal_ordered_set.cpp"
template <class T> class less_equal_ordered_set {
public:
  using value_type = T;
  static constexpr bool compare(const T &x, const T &y) noexcept {
    return x <= y;
  }
};
#line 1 "other/min_semigroup.cpp"
template <class W> class min_semigroup {
  using T = typename W::value_type;

public:
  using value_type = T;
  static constexpr T operation(const T &l, const T &r) noexcept {
    return W::compare(l, r) ? l : r;
  }
};
#line 1 "other/opposite_ordered_set.cpp"
template <class W> class opposite_ordered_set {
  using T = typename W::value_type;

public:
  using value_type = T;
  static constexpr bool compare(const T &l, const T &r) noexcept {
    return W::compare(r, l);
  }
};
#line 1 "other/semigroup_to_monoid.cpp"
#include <optional>
#include <utility>

template <class S> class semigroup_to_monoid {
  using T = std::optional<typename S::value_type>;

public:
  using value_type = T;
  static constexpr T operation(const T &l, const T &r) noexcept {
    if (!l)
      return r;
    if (!r)
      return l;
    return T(std::in_place, S::operation(*l, *r));
  }
  static constexpr T identity{std::nullopt};
};
#line 10 "test/larsch.test.cpp"

#include <iostream>
#include <limits>

int main() {
#line 1 "other/fast_ios.cpp"
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
#line 16 "test/larsch.test.cpp"

  static constexpr i64 inf = std::numeric_limits<i64>::max() / 2;

  usize n, l;
  std::cin >> n >> l;

  segment_tree<semigroup_to_monoid<
      min_semigroup<opposite_ordered_set<less_equal_ordered_set<i64>>>>>
      seg(n);
  for (usize i = 0; i != n; ++i) {
    i64 a;
    std::cin >> a;
    seg.update(i, a);
  }

  std::vector<i64> dp(n + 1);
  dp[0] = 0;

  const auto get = [&](const usize to, const usize from) -> i64 {
    if (to - from < l) {
      return -inf;
    } else {
      return dp[from] + *seg.fold(from, to);
    }
  };

  const auto select = [&](const usize to, const usize from0,
                          const usize from1) -> bool {
    if (to - from1 < l) {
      return false;
    }
    return get(to, from0) < get(to, from1);
  };

  const auto update = [&](const usize i, const usize from) {
    dp[i] = get(i, from);
  };

  larsch(n, select, update);

  std::cout << dp[n] << "\n";

  return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 13964
final_rank: 13

code_snippet: #include <cmath>
#include <vector>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <algorithm>
#include <set>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <climits>
#include <array>
#include <unordered_set>
#include <unordered_map>
#include <memory>
#include <functional>
#include <cfloat>
#include <numeric>
#include <random>
#include <sstream>
#include <bitset>
#include <complex>
#include <chrono>
#include <cassert>
int limit;
std::vector<int> value;
class MaxSegTree {
	std::vector<std::vector<int>> vec;
public:
	MaxSegTree(const std::vector<int>& value) : vec{ value } {
		while (vec.back().size() > 1) {
			vec.emplace_back(vec.back().size() >> 1);
		}
		for (auto i = 1; i < vec.size(); ++i) {
			for (auto j = 0; j < vec[i].size(); ++j) {
				vec[i][j] = std::max(vec[i - 1][j << 1], vec[i - 1][(j << 1) + 1]);
			}
		}
	}
	int get(const int from, const int until) const {
		int l = from, r = until - 1;
		int result{ INT_MIN };
		for (const auto& v : vec) {
			if ((l & 1) == 1) {
				result = std::max(result, v[l]);
				++l;
			}
			if ((r & 1) == 0) {
				result = std::max(result, v[r]);
				--r;
			}
			l >>= 1;
			r >>= 1;
			if (l > r) return result;
		}
		return result;
	}
};
void set_vec(const int dfirst_from, const int dfirst_until, const int dlast_from, const int dlast_until, std::vector<long long int>& dest, const MaxSegTree &seg) {
	if (dfirst_from >= dfirst_until) return;
	const int current = (dfirst_from + dfirst_until) >> 1;
	const auto from = std::max(dlast_from + 1, current + limit);
	int max_pos{ from - 1 };
	int max_value = seg.get(current, from);
	long long int result{ max_value + dest[from] };
	for (auto i = from; i < dlast_until; ++i) {
		max_value = std::max(max_value, value[i]);
		if (result < max_value + dest[i + 1]) {
			result = max_value + dest[i + 1];
			max_pos = i;
		}
	}
	dest[current] = std::max(dest[current], result);
	set_vec(dfirst_from, current, dlast_from, max_pos + 1, dest, seg);
	set_vec(current + 1, dfirst_until, max_pos, dlast_until, dest, seg);
}

long long int large() {
	std::vector<long long int> vec(value.size() + 1, LLONG_MIN);
	vec.back() = 0;
	MaxSegTree seg(value);
	for (auto count = 0; count <= value.size(); count += limit) {
		set_vec(0, value.size() - limit + 1, limit - 1, value.size(), vec, seg);
	}
	return vec.front();
}
long long int small() {
	std::vector<long long int> memo(value.size() + 1, LLONG_MIN);
	memo.back() = 0;
	std::vector<int> positive(value.size() + 1, value.size());
	MaxSegTree seg(value);
	for (int i = value.size() - 1; i >= 0; --i) {
		if (value[i] > 0) {
			positive[i] = i + 1;
		}
		else {
			positive[i] = positive[i + 1];
		}
	}
	for (int from = value.size() - limit; from >= 0; --from) {
		const auto start = std::max(from + limit, positive[from]);
		int max_value = seg.get(from, start);
		long long int result{ max_value + memo[start] };
		for (auto until = start + 1; until <= std::min<int>(value.size(), start + limit); ++until) {
			max_value = std::max(max_value, value[until - 1]);
			result = std::max(result, max_value + memo[until]);
		}
		memo[from] = result;
	}
	return memo.front();
}


int main() {
	int n; std::cin >> n >> limit;
	const int sqrt = std::sqrt(n);
	value = std::vector<int>(n);
	for (auto& v : value) std::cin >> v;
	const auto max = *std::max_element(value.begin(), value.end());
	if (max <= 0) {
		std::cout << max << '\n';
	}else if (limit > sqrt) {
		std::cout << large() << '\n';
	}
	else {
		std::cout << small() << '\n';
	}
}
accuracy: 1
time_ms: 1530
memory_kb: 6124
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
template<class T> bool chmin(T& a,T b){if(a>b) {a = b; return true;} return false;}
template<class T> bool chmax(T& a,T b){if(a<b) {a = b; return true;} return false;}
#define all(x) (x).begin(),(x).end()
#define debug(x)  cerr << #x << " = " << (x) << endl;

template<typename Monoid,typename F>
class SegmentTree{
private:
    int sz;
    vector<Monoid> seg;
    const F op;
    const Monoid e;
public:
    SegmentTree(int n,const F op,const Monoid &e):op(op),e(e){
        sz = 1;
        while(sz<=n) sz <<= 1;
        seg.assign(2*sz,e);
    }
    void set(int k, const Monoid &x){
        seg[k+sz] = x;
    }
    void build(){
        for(int i=sz-1;i>0;i--){
            seg[i] = op(seg[2*i],seg[2*i+1]);
        }
    }
    void update(int k,const Monoid &x){
        k += sz;
        seg[k] = x;
        while(k>>=1){
            seg[k] = op(seg[2*k],seg[2*k+1]);
        }
    }
    Monoid query(int l,int r){
        Monoid L = e,R = e;
        for(l+=sz,r+=sz;l<r;l>>=1,r>>=1){
            if(l&1) L = op(L,seg[l++]);
            if(r&1) R = op(seg[--r],R);
        }
        return op(L,R);
    }
    Monoid operator[](const int &k)const{
        return seg[k+sz];
    }
};

constexpr ll inf = 1e18;

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N,L;
    cin >> N >> L;
    vec<int> A(N);
    for(auto& x:A) cin >> x;
    SegmentTree dp(N+1,[](ll a,ll b){return max(a,b);},-inf);
    SegmentTree seg(N+1,[](ll a,ll b){return max(a,b);},-inf);
    dp.set(0,0);
    dp.build();
    for(int i=0;i<N;i++) seg.set(i,A[i]);
    seg.build();
    for(int i=0;i<N;i++){
        ll val = max((i>=L? dp[i]:-inf),seg.query(i-L+1,i+1)+dp.query(0,i-L+2));
        dp.update(i+1,val);
    }
//    for(int i=0;i<=N;i++) cerr << dp[i] << (i!=N? " ":"\n");
    cout << dp.query(L,N+1) << "\n";
}
accuracy: 1
time_ms: 20
memory_kb: 11912
final_rank: 10