Problem:
E: LISum
問題
長さ $N$ の数列 $A$ が与えられる。
		数列 $A$ の最長増加部分列のひとつを $B$ とするとき、$\sum B_i$ の最大値を求めよ。
数列 $A$ の最長増加部分列とは、すべての $i < j$ で $A_i < A_j$ を満たす部分列のうち、最長なものを示す。
制約
入力値は全て整数である。
$1 \leq N \leq 10^5$
$0 \leq A_i \leq 10^5$
入力形式
入力は以下の形式で与えられる。
$N$
$A_1 \dots A_N$
出力
数列 $A$ の最長増加部分列のひとつを $B$ とするとき、$\sum B_i$ の最大値を出力せよ。また、末尾に改行も出力せよ。
サンプル
サンプル入力 1
4
6 4 7 8
サンプル出力 1
21
最長増加部分列は $ (6, 7, 8)$ と $(4, 7, 8)$ である。よって最大値は $21$ である。
サンプル入力 2
3
1000 2 3
サンプル出力 2
5
最長増加部分列は $(2,3)$ のみである。
サンプル入力 3
7
17 17 13 4 20 12 15
サンプル出力 3
31
サンプル入力 4
7
19 16 14 9 4 20 2
サンプル出力 4
39

Submitted solutions:

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

using ll = long long;
using pll = pair<ll, ll>;

template<typename Monoid>
class segment_tree {
    using T = typename Monoid::type;

public:
    segment_tree(std::vector<T> const& init)
        : sz(init.size()), n(expand(init.size()))
    {
        dat.assign(n*2, Monoid::id());
        std::copy(begin(init), end(init), begin(dat) + n);
        for(int i = n - 1; i >= 0; --i) {
            dat[i] = Monoid::op(dat[i * 2], dat[i * 2 + 1]);
        }
    }

    segment_tree(int const n_, T const& init = Monoid::id())
        : segment_tree(std::vector<T>(n_, init))
    {}

    void update(int p, T val) {
        assert(0 <= p && p < sz);
        dat[p += n] = val;
        while(p /= 2) {
            dat[p] = Monoid::op(dat[p * 2], dat[p * 2 + 1]);
        }
    }

    // [l, r)
    T query(int l, int r) const {
        assert(0 <= l && l <= r && r <= sz);
        l += n, r += n;
        T res1 = Monoid::id(), res2 = Monoid::id();
        while(l != r) {
            if(l & 1) res1 = Monoid::op(res1, dat[l++]);
            if(r & 1) res2 = Monoid::op(dat[--r], res2);
            l /= 2, r /= 2;
        }
        return Monoid::op(res1, res2);
    }

private:
    int expand(int n_) const {
        assert(n_ >= 1);
        return n_ == 1 ? n_ : expand((n_ + 1) / 2) * 2;
    }

private:
    const int sz, n;
    std::vector<T> dat;
};

struct LIS {
    using type = pll;
    static type id() {
        return make_pair(0, 0);
    }
    static type op(type const& l, type const& r) {
        return max(l, r);
    }
};

int main() {
    int n; cin >> n;
    vector<int> a(n), as;
    for(int i = 0; i < n; ++i) {
        cin >> a[i];
        as.push_back(a[i]);
    }
    sort(begin(as), end(as));
    as.erase(unique(begin(as), end(as)), end(as));
    for(int i = 0; i < n; ++i) {
        a[i] = lower_bound(begin(as), end(as), a[i]) - begin(as);
    }

    segment_tree<LIS> seg(n);
    for(int i = 0; i < n; ++i) {
        auto ma = seg.query(0, a[i]);
        ma.first += 1;
        ma.second += as[a[i]];
        if(seg.query(a[i], a[i] + 1) < ma) {
            seg.update(a[i], ma);
        }
    }

    cout << seg.query(0, n).second << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 9768
final_rank: 11

code_snippet: #include <iostream>
#include <vector>
using namespace std;


int inv_lower_bound(vector<pair<long long, long long>> A, long long x){
	int mn = -1;
	int mx = A.size()-1;
	while(mx - mn > 1){
		int ce = (mn+mx)/2;
		if(A[ce].first >= x){
			mn = ce;
		}else{
			mx = ce;
		}
	}
	return mx;
}

int main(){
	int n;cin>>n;
	vector<pair<long long, long long>> A[n];
	vector<long long> nw(n,1000000);
	long mx = 0;
	for(int i = 0; n > i; i++){
		long long z;cin>>z;
		auto x = lower_bound(nw.begin(), nw.end(), z) - nw.begin();
		if(x > 0){
			auto y = inv_lower_bound(A[x-1], z);
			A[x].push_back({z, z+A[x-1][y].second});
			nw[x] = z;
			mx = max(mx,x);
		}else{
			A[x].push_back({z, z});
			mx = max(mx,x);
			nw[x] = z;
		}
	}
	long long ans = 0;
	for(int i = 0; A[mx].size() > i; i++){
		ans = max(ans, A[mx][i].second);
	}
	cout << ans << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 9388
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MOD 1000000007
//#define MOD 998244353
#define INF 1000000010
#define EPS 1e-9
#define FF first
#define S second

#define debug(x) cout<<x<<endl;
#define repi(i,x,n) for(int i=x;i<n;i++)
#define rep(i,n) repi(i,0,n)
#define lp(i,n) repi(i,0,n)
#define repn(i,n) for(int i=n;i>=0;i--)
//#define int long long
#define endl "\n"

typedef pair<long long int,long long int> PII;
typedef pair<int,string> PIS;
typedef pair<string,int> PSI;

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

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

template< typename T, typename F >
struct SegmentTree {
  int n, sz;
  vector< T > seg;

  const F f;
  const T ti;

  SegmentTree() = default;

  explicit SegmentTree(int n, const F f, const T &ti) : n(n), f(f), ti(ti) {
    sz = 1;
    while(sz < n) sz <<= 1;
    seg.assign(2 * sz, ti);
  }

  explicit SegmentTree(const vector< T > &v, const F f, const T &ti) :
      SegmentTree((int) v.size(), f, ti) {
    build(v);
  }

  void build(const vector< T > &v) {
    assert(n == (int) v.size());
    for(int k = 0; k < n; k++) seg[k + sz] = v[k];
    for(int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void set(int k, const T &x) {
    k += sz;
    seg[k] = x;
    while(k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  T get(int k) const {
    return seg[k + sz];
  }

  T operator[](const int &k) const {
    return get(k);
  }

  void apply(int k, const T &x) {
    k += sz;
    seg[k] = f(seg[k], x);
    while(k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  T prod(int l, int r) const {
    T L = ti, R = ti;
    for(l += sz, r += sz; l < r; l >>= 1, r >>= 1) {
      if(l & 1) L = f(L, seg[l++]);
      if(r & 1) R = f(seg[--r], R);
    }
    return f(L, R);
  }

  T all_prod() const {
    return seg[1];
  }

  template< typename C >
  int find_first(int l, const C &check) const {
    if(l >= n) return n;
    l += sz;
    T sum = ti;
    do {
      while((l & 1) == 0) l >>= 1;
      if(check(f(sum, seg[l]))) {
        while(l < sz) {
          l <<= 1;
          auto nxt = f(sum, seg[l]);
          if(not check(nxt)) {
            sum = nxt;
            l++;
          }
        }
        return l + 1 - sz;
      }
      sum = f(sum, seg[l++]);
    } while((l & -l) != l);
    return n;
  }

  template< typename C >
  int find_last(int r, const C &check) const {
    if(r <= 0) return -1;
    r += sz;
    T sum = ti;
    do {
      r--;
      while(r > 1 and (r & 1)) r >>= 1;
      if(check(f(seg[r], sum))) {
        while(r < sz) {
          r = (r << 1) + 1;
          auto nxt = f(seg[r], sum);
          if(not check(nxt)) {
            sum = nxt;
            r--;
          }
        }
        return r - sz;
      }
      sum = f(seg[r], sum);
    } while((r & -r) != r);
    return -1;
  }
};

template< typename T, typename F >
SegmentTree< T, F > get_segment_tree(int N, const F &f, const T &ti) {
  return SegmentTree(N, f, ti);
}

template< typename T, typename F >
SegmentTree< T, F > get_segment_tree(const vector< T > &v, const F &f, const T &ti) {
  return SegmentTree(v, f, ti);
}

PII dp[100010];
auto seg = get_segment_tree(100010,[](PII a,PII b) {return max(a,b); },make_pair(0,0));

signed main(){
    int n;
    cin>>n;
    
    vector<int> v(n);
    rep(i,n) cin>>v[i];
    
    
    rep(i,100010){
      dp[i]={0,0};
    }
    
    
    //cout<<"A"<<endl;
    rep(i,n){
      //cout<<"B"<<endl;
      PII prev=seg.prod(0,v[i]);
      //cout<<"C"<<endl;
      //cout<<prev.FF<<" "<<prev.S<<endl;
      prev.FF++;
      prev.S+=v[i];
      
      chmax(dp[v[i]],prev);
      //cout<<v[i]<<" "<<dp[v[i]].S<<endl;
      seg.set(v[i],dp[v[i]]);
    }
    PII ans={0,0};
    rep(i,100010){
      if(ans < dp[i]) ans=dp[i];
    }
    cout<<ans.S<<endl;
}
accuracy: 0.9847328244274809
time_ms: 30
memory_kb: 7072
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MOD 1000000007
//#define MOD 998244353
#define INF 1000000010
#define EPS 1e-9
#define FF first
#define S second

#define debug(x) cout<<x<<endl;
#define repi(i,x,n) for(int i=x;i<n;i++)
#define rep(i,n) repi(i,0,n)
#define lp(i,n) repi(i,0,n)
#define repn(i,n) for(int i=n;i>=0;i--)
#define int long long
#define endl "\n"

typedef pair<int,int> PII;
typedef pair<int,string> PIS;
typedef pair<string,int> PSI;

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

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

template< typename T, typename F >
struct SegmentTree {
  int n, sz;
  vector< T > seg;

  const F f;
  const T ti;

  SegmentTree() = default;

  explicit SegmentTree(int n, const F f, const T &ti) : n(n), f(f), ti(ti) {
    sz = 1;
    while(sz < n) sz <<= 1;
    seg.assign(2 * sz, ti);
  }

  explicit SegmentTree(const vector< T > &v, const F f, const T &ti) :
      SegmentTree((int) v.size(), f, ti) {
    build(v);
  }

  void build(const vector< T > &v) {
    assert(n == (int) v.size());
    for(int k = 0; k < n; k++) seg[k + sz] = v[k];
    for(int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void set(int k, const T &x) {
    k += sz;
    seg[k] = x;
    while(k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  T get(int k) const {
    return seg[k + sz];
  }

  T operator[](const int &k) const {
    return get(k);
  }

  void apply(int k, const T &x) {
    k += sz;
    seg[k] = f(seg[k], x);
    while(k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  T prod(int l, int r) const {
    T L = ti, R = ti;
    for(l += sz, r += sz; l < r; l >>= 1, r >>= 1) {
      if(l & 1) L = f(L, seg[l++]);
      if(r & 1) R = f(seg[--r], R);
    }
    return f(L, R);
  }

  T all_prod() const {
    return seg[1];
  }

  template< typename C >
  int find_first(int l, const C &check) const {
    if(l >= n) return n;
    l += sz;
    T sum = ti;
    do {
      while((l & 1) == 0) l >>= 1;
      if(check(f(sum, seg[l]))) {
        while(l < sz) {
          l <<= 1;
          auto nxt = f(sum, seg[l]);
          if(not check(nxt)) {
            sum = nxt;
            l++;
          }
        }
        return l + 1 - sz;
      }
      sum = f(sum, seg[l++]);
    } while((l & -l) != l);
    return n;
  }

  template< typename C >
  int find_last(int r, const C &check) const {
    if(r <= 0) return -1;
    r += sz;
    T sum = ti;
    do {
      r--;
      while(r > 1 and (r & 1)) r >>= 1;
      if(check(f(seg[r], sum))) {
        while(r < sz) {
          r = (r << 1) + 1;
          auto nxt = f(seg[r], sum);
          if(not check(nxt)) {
            sum = nxt;
            r--;
          }
        }
        return r - sz;
      }
      sum = f(seg[r], sum);
    } while((r & -r) != r);
    return -1;
  }
};

template< typename T, typename F >
SegmentTree< T, F > get_segment_tree(int N, const F &f, const T &ti) {
  return SegmentTree(N, f, ti);
}

template< typename T, typename F >
SegmentTree< T, F > get_segment_tree(const vector< T > &v, const F &f, const T &ti) {
  return SegmentTree(v, f, ti);
}

PII dp[100010];
auto seg = get_segment_tree(100010,[](PII a,PII b) {return max(a,b); },make_pair(0,0));

signed main(){
    int n;
    cin>>n;
    
    vector<int> v(n);
    rep(i,n) cin>>v[i];
    
    
    rep(i,100010){
      dp[i]={0,0};
    }
    
    
    //cout<<"A"<<endl;
    rep(i,n){
      //cout<<"B"<<endl;
      PII prev=seg.prod(0,v[i]);
      //cout<<"C"<<endl;
      //cout<<prev.FF<<" "<<prev.S<<endl;
      prev.FF++;
      prev.S+=v[i];
      
      chmax(dp[v[i]],prev);
      //cout<<v[i]<<" "<<dp[v[i]].S<<endl;
      seg.set(v[i],dp[v[i]]);
    }
    PII ans={0,0};
    rep(i,100010){
      if(ans < dp[i]) ans=dp[i];
    }
    cout<<ans.S<<endl;
}
accuracy: 0.9847328244274809
time_ms: 30
memory_kb: 7612
final_rank: 20

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define MOD 1000000007
//#define MOD 998244353
#define INF 1000000010
#define EPS 1e-9
#define FF first
#define S second

#define debug(x) cout<<x<<endl;
#define repi(i,x,n) for(int i=x;i<n;i++)
#define rep(i,n) repi(i,0,n)
#define lp(i,n) repi(i,0,n)
#define repn(i,n) for(int i=n;i>=0;i--)
#define int long long
#define endl "\n"

typedef pair<int,int> PII;
typedef pair<int,string> PIS;
typedef pair<string,int> PSI;

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

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

template< typename T, typename F >
struct SegmentTree {
  int n, sz;
  vector< T > seg;

  const F f;
  const T ti;

  SegmentTree() = default;

  explicit SegmentTree(int n, const F f, const T &ti) : n(n), f(f), ti(ti) {
    sz = 1;
    while(sz < n) sz <<= 1;
    seg.assign(2 * sz, ti);
  }

  explicit SegmentTree(const vector< T > &v, const F f, const T &ti) :
      SegmentTree((int) v.size(), f, ti) {
    build(v);
  }

  void build(const vector< T > &v) {
    assert(n == (int) v.size());
    for(int k = 0; k < n; k++) seg[k + sz] = v[k];
    for(int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void set(int k, const T &x) {
    k += sz;
    seg[k] = x;
    while(k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  T get(int k) const {
    return seg[k + sz];
  }

  T operator[](const int &k) const {
    return get(k);
  }

  void apply(int k, const T &x) {
    k += sz;
    seg[k] = f(seg[k], x);
    while(k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  T prod(int l, int r) const {
    T L = ti, R = ti;
    for(l += sz, r += sz; l < r; l >>= 1, r >>= 1) {
      if(l & 1) L = f(L, seg[l++]);
      if(r & 1) R = f(seg[--r], R);
    }
    return f(L, R);
  }

  T all_prod() const {
    return seg[1];
  }

  template< typename C >
  int find_first(int l, const C &check) const {
    if(l >= n) return n;
    l += sz;
    T sum = ti;
    do {
      while((l & 1) == 0) l >>= 1;
      if(check(f(sum, seg[l]))) {
        while(l < sz) {
          l <<= 1;
          auto nxt = f(sum, seg[l]);
          if(not check(nxt)) {
            sum = nxt;
            l++;
          }
        }
        return l + 1 - sz;
      }
      sum = f(sum, seg[l++]);
    } while((l & -l) != l);
    return n;
  }

  template< typename C >
  int find_last(int r, const C &check) const {
    if(r <= 0) return -1;
    r += sz;
    T sum = ti;
    do {
      r--;
      while(r > 1 and (r & 1)) r >>= 1;
      if(check(f(seg[r], sum))) {
        while(r < sz) {
          r = (r << 1) + 1;
          auto nxt = f(seg[r], sum);
          if(not check(nxt)) {
            sum = nxt;
            r--;
          }
        }
        return r - sz;
      }
      sum = f(seg[r], sum);
    } while((r & -r) != r);
    return -1;
  }
};

template< typename T, typename F >
SegmentTree< T, F > get_segment_tree(int N, const F &f, const T &ti) {
  return SegmentTree(N, f, ti);
}

template< typename T, typename F >
SegmentTree< T, F > get_segment_tree(const vector< T > &v, const F &f, const T &ti) {
  return SegmentTree(v, f, ti);
}

signed main(){
    int n;
    cin>>n;
    
    vector<int> v(n);
    rep(i,n) cin>>v[i];
    PII dp[100010];
    
    rep(i,100010){
      dp[i]={0,0};
    }
    
    auto seg = get_segment_tree(100010,[](PII a,PII b) {return max(a,b); },make_pair(0,0));
    
    rep(i,n){
      PII prev=seg.prod(0,v[i]);
      //cout<<prev.FF<<" "<<prev.S<<endl;
      prev.FF++;
      prev.S+=v[i];
      
      chmax(dp[v[i]],prev);
      //cout<<v[i]<<" "<<dp[v[i]].S<<endl;
      seg.set(v[i],dp[v[i]]);
    }
    PII ans={0,0};
    rep(i,100010){
      chmax(ans,dp[i]);
    }
    cout<<ans.S<<endl;
}
accuracy: 0.9847328244274809
time_ms: 30
memory_kb: 7568
final_rank: 19

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

const int inf = (int)1e9;

template <class T>
void eout(const vector<T>& A) {
    for (auto a : A) cout << a << ' ';
    cout << endl;
}

int main() {
    int N; cin >> N;
    vector<int> A(N);
    for (auto& a : A) cin >> a;
    vector<int> dp(N + 1, inf);
    vector<vector<int>> minus(N + 1, vector(1, -inf));
    vector<vector<i64>> sums(N + 1, vector(1, 0LL));
    for (auto a : A) {
        int pos = lower_bound(dp.begin(), dp.end(), a) - dp.begin();
        if (pos == 0) {
            dp[0] = a;
            minus[0].push_back(-a);
            sums[0].push_back(a);
        }
        else {
            int sumpos = upper_bound(minus[pos - 1].begin(), minus[pos - 1].end(), -a) - minus[pos - 1].begin();
            dp[pos] = a;
            minus[pos].push_back(-a);
            i64 v = sums[pos - 1][sumpos] + a;
            sums[pos].push_back(v);
        }
    }


    i64 ans = 0LL;
    int lis = lower_bound(dp.begin(), dp.end(), inf) - dp.begin();
    assert(lis > 0);
    for (auto& s : sums[lis - 1]) ans = max(ans, s);

    cout << ans << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 16344
final_rank: 16

code_snippet: #include <iostream>
#include <vector>
using namespace std;


int inv_lower_bound(vector<pair<long long, long long>> A, long long x){
	int mn = -1;
	int mx = A.size()-1;
	while(mx - mn > 1){
		int ce = (mn+mx)/2;
		if(A[ce].first >= x){
			mn = ce;
		}else{
			mx = ce;
		}
	}
	return mx;
}

int main(){
	int n;cin>>n;
	vector<pair<long long, long long>> A[n];
	vector<long long> nw(n,1000000);
	long mx = 0;
	for(int i = 0; n > i; i++){
		long long z;cin>>z;
		auto x = lower_bound(nw.begin(), nw.end(), z) - nw.begin();
		if(x > 0){
			auto y = inv_lower_bound(A[x-1], z);
			A[x].push_back({z, z+A[x-1][y].second});
			nw[x] = z;
			mx = max(mx,x);
		}else{
			A[x].push_back({z, z});
			mx = max(mx,x);
			nw[x] = z;
		}
	}
	long long ans = 0;
	for(int i = 0; A[mx].size() > i; i++){
		ans = max(ans, A[mx][i].second);
	}
	cout << ans << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 9324
final_rank: 9

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

using ll = long long;

ll func(){
  int n;
  cin >> n;
  vector<ll> dp(n+10,1e9);
  vector<map<ll,ll>> sums(n+10);
  using P = pair<ll,ll>;
  P res(-1,-1);
  for(int i=0;i<n;++i){
    ll v;
    cin >> v;
    int p = lower_bound(dp.begin(),dp.end(),v) - dp.begin();
    dp[p] = v;
    auto itr = sums[p].lower_bound(v);
    ll add = 0;
    if(itr != sums[p].begin()){
      --itr;
      add = itr->second;
    }
    ll x = add + v;
    sums[p+1][v] = x;
    P next(p,x);
    res = max(res, next);
  }
  return res.second;
}

int main(){
  cout << func() << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 14840
final_rank: 15

code_snippet: #include <iostream>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <algorithm>
#include <numeric>
#include <queue>
#include <cassert>
#include <cmath>
#include <bitset>
using namespace std;

int LIS(const vector<long long> &V) {
  long long INF = (long long)1e18;
  vector<long long> dp(V.size(), INF);
  for (auto v : V) {
    auto itr = lower_bound(dp.begin(), dp.end(), v);
    if (itr != V.end()) *itr = v;
  }
  return lower_bound(dp.begin(), dp.end(), INF) - dp.begin();
}

int main() {
  int n;
  cin >> n;
  vector<long long> a(n);
  for (int i = 0; i < n; i++) cin >> a[i];

  long long INF = (long long)1e18;
  vector<long long> l(n, INF);
  vector<int> dp(n);
  for (int i = 0; i < n; i++) {
    auto itr = lower_bound(l.begin(), l.end(), a[i]);
    if (itr != l.end()) *itr = a[i];
    dp[i] = itr-l.begin();
  }
  //for (int i = 0; i < n; i++) cout << dp[i] << " "; cout << endl;
  int m = LIS(a);
  //cout << "m = " << m << endl;
  vector<long long> b(m+1, 0);
  b[m] = INF;
  for (int i = n-1; i >= 0; i--)
    if (a[i] < b[dp[i]+1]) b[dp[i]] = max(b[dp[i]], a[i]);
  //cout << "hi" << endl;
  //for (int i = 0; i < m; i++) cout << b[i] << " "; cout << endl;
  long long ans = 0;
  for (int i = 0; i < m; i++) ans += b[i];
  cout << ans << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 5724
final_rank: 5

code_snippet: #pragma GCC optimize("Ofast")
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <queue>
#include <cstdio>
#include <ctime>
#include <assert.h>
#include <chrono>
#include <random>
#include <numeric>
#include <set>
#include <deque>
#include <stack>
#include <sstream>
#include <utility>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
#include <array>
#include <bitset>
using namespace std;
typedef long long int ll;
typedef unsigned long long ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) {
    return (ull)rng() % B;
}
inline ll time() {
    return static_cast<long double>(chrono::duration_cast<chrono::nanoseconds>(chrono::steady_clock::now().time_since_epoch()).count()) * 1e-9;
}

template <class S, S (*op)(S, S), S (*e)()>
struct segtree {
    int n;
    vector<S> tree;
    segtree() : segtree(0) {}
    segtree(int n) : n(n), tree(vector<S>(n<<1, e())) {}
    void update(int k) { tree[k] = op(tree[k<<1|0], tree[k<<1|1]); }
    S operator[](int i) {return tree[i+n]; }
    void set(int i, S x) {
        i += n;
        tree[i] = x;
        while(i >>= 1) {
            update(i);
        }
    }
    // [l,r)
    S query(int l, int r) {
        S sml = e(), smr = e();
        for(l += n, r += n; l < r; l >>= 1, r >>= 1){
            if(l & 1) sml = op(sml, tree[l++]);
            if(r & 1) smr = op(tree[--r], smr);
        }
        return op(sml,smr);
    }
};

using P = pair<int,ll>;
P op(P a,P b){return max(a,b);}
P e(){return {0,0LL};}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n; cin >> n;
    const int N = 1e5;
    segtree<P,op,e> seg(N+1);
    for(int i=0;i<n;i++){
        int a; cin >> a;
        auto r = seg.query(0,a);
        P p = r;
        r.first++; r.second += a;
        if(seg[a] < r) seg.set(a,r);
    }
    cout << seg.query(0,N+1).second << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 6280
final_rank: 6

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
//using namespace atcoder;
const double pi = 3.141592653589793238462643383279;
using namespace std;
//typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<long long, long long> PLL;
typedef pair<int, PII> TIII;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;

//container util
//------------------------------------------
#define ALL(a) (a).begin(), (a).endf()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SQ(a) ((a) * (a))
#define EACH(i, c) for (typeof((c).begin()) i = (c).begin(); i != (c).endf(); ++i)
#define EXIST(s, e) ((s).find(e) != (s).endf())
#define SORT(c) sort((c).begin(), (c).endf())

//repetition
//------------------------------------------
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define MOD 1000000007

#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define trav(a, x) for (auto &a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
const double EPS = 1e-4, PI = acos(-1);
//ここから編集    
typedef string::const_iterator State;

struct BIT{
  vector<pair<ll, ll>> node;

  int N;
  BIT(int n){
    N = n;
    node.resize(N+1);
  }
  void add(int i, pair<ll, ll> x){
    i++;
    while(i <= N){
      node[i] = max(x, node[i]);
      i += (i & -i);
    }
  }
  pair<ll, ll> qry(int i){
    pair<ll, ll> res = make_pair(0,0);
    while(i > 0){
      if(res.first == node[i].first){
        if(res.second < node[i].second) res = node[i];
      }else{
        if(res.first < node[i].first) res = node[i];
      }
      i -= (i & -i);
    }
    return res;
  }
};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);

    int N;
    cin >> N;
    vector<ll> a(N);
    REP(i,N) cin >> a[i];

    BIT bit(101010);

    
    REP(i,N){
        auto p = bit.qry(a[i]);

        bit.add(a[i], make_pair(p.first+1, p.second+a[i]));
    }
    cout << bit.qry(101010).second << endl;
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 5196
final_rank: 4

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

using namespace std;

const int INF = 1e9;

int lower_b(vector<int> dp,int a){
    int lb = 0,ub=dp.size();
    while(ub-lb>1){
        int mid = (lb+ub)/2;
        if(dp[mid]<=a){
            ub = mid;
        }
        else
        {
            lb = mid;
        }
    }
    return ub;
}

int main()
{
    int N;
    cin >> N;
    vector<long long> A(N);
    for (int i = 0; i < N;i++){
        cin >> A[i];
    }
    
    vector<int> dp(N,INF);
    vector<set<int>> numbers(N);
    for (int i = 0;i<N;i++){
        auto it = lower_bound(dp.begin(), dp.end(), A[i]);
        *it = A[i];
        numbers[it - dp.begin()].insert(A[i]);
    }
    int len = lower_bound(dp.begin(),dp.end(),INF)-dp.begin();
    int l = INF;

    long long res = 0;
    for (int i = len - 1; i >= 0; i--)
    {
        auto it = numbers[i].lower_bound(l);
        it--;
        l = *it;
        res += *it;
    }
 
    cout << res << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 13392
final_rank: 12

code_snippet: #define ASSERT_LV 1
// header {{{
#ifndef ASSERT_LV
# define ASSERT_LV 1
#endif
#if ASSERT_LV == 0
# define NDEBUG
#endif

#if defined(__GNUC__) && !defined(__clang__)
#include <bits/stdc++.h>
#else
#include <cassert>
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
//#include <clocale>
#include <cmath>
//#include <csetjmp>
//#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
//#include <cwchar>
//#include <cwctype>
#if __cplusplus >= 201103L
//#include <ccomplex>
#include <cfenv>
#include <cinttypes>
//#include <cstdalign>
//#include <cstdbool>
#include <cstdint>
//#include <ctgmath>
//#include <cuchar>
#endif
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
//#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#if __cplusplus >= 201103L
#include <array>
//#include <atomic>
#include <chrono>
//#include <codecvt>
//#include <condition_variable>
#include <forward_list>
//#include <future>
#include <initializer_list>
//#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
//#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#endif
#if __cplusplus >= 201402L
//#include <shared_mutex>
#endif
#if __cplusplus >= 201703L
#include <any>
//#include <charconv>
//#include <execution>
//#include <filesystem>
#include <optional>
//#include <memory_resource>
#include <string_view>
#include <variant>
#endif
#endif
using namespace std;

using i8  = int8_t;
using u8  = uint8_t;
using i16 = int16_t;
using u16 = uint16_t;
using i32 = int32_t;
using u32 = uint32_t;
using i64 = int64_t;
using u64 = uint64_t;
#ifdef __SIZEOF_INT128__
using i128 = __int128;
using u128 = unsigned __int128;
#endif

using f32 = float;
using f64 = double;
using f80 = long double;

template<class T> constexpr T PROCON_INF();
template<> constexpr i32 PROCON_INF<i32>() { return 1'010'000'011; }
template<> constexpr i64 PROCON_INF<i64>() { return INT64_C(1'010'000'000'000'000'017); }
template<> constexpr f32 PROCON_INF<f32>() { return 1e19F; }
template<> constexpr f64 PROCON_INF<f64>() { return 1e100; }
template<> constexpr f80 PROCON_INF<f80>() { return 1e100L; }
// }}}

using Int  = i64;
using Real = f80;

constexpr Int MOD = 1'000'000'007;
//constexpr Int MOD = 998'244'353;

constexpr Real EPS = Real(1e-10L);

constexpr int  COUT_PREC      = 15;
constexpr bool COUT_AUTOFLUSH = false;

// procon {{{

static_assert(is_same<Int,i64>::value || is_same<Int,i32>::value, "");
static_assert(is_same<Real,f80>::value || is_same<Real,f64>::value || is_same<Real,f32>::value, "");

#define CPP_STR(x) CPP_STR_I(x)
#define CPP_CAT(x,y) CPP_CAT_I(x,y)
#define CPP_STR_I(args...) #args
#define CPP_CAT_I(x,y) x ## y

#define SFINAE(pred...) std::enable_if_t<(pred), std::nullptr_t> = nullptr

#define ASSERT(expr...) assert((expr))
#if defined(PROCON_LOCAL) || ASSERT_LV >= 2
# define ASSERT_LOCAL(expr...) assert((expr))
#else
# define ASSERT_LOCAL(expr...)
#endif

constexpr Int  INF  = PROCON_INF<Int>();
constexpr Real FINF = PROCON_INF<Real>();

constexpr Real PI = Real(3.141592653589793238462643383279502884197L);

template<class T> constexpr T SQRT_MAX();
template<> constexpr i32 SQRT_MAX<i32>() { return 46340; }
template<> constexpr i64 SQRT_MAX<i64>() { return INT64_C(3037000499); }

template<class T, SFINAE(is_signed<T>::value)>
constexpr T ABS(T x) noexcept {
    return x < 0 ? -x : x;
}

constexpr bool LT_EPS(Real lhs, Real rhs, Real eps=EPS) { return lhs < rhs-eps; }
constexpr bool GT_EPS(Real lhs, Real rhs, Real eps=EPS) { return lhs > rhs+eps; }
constexpr bool EQ_EPS(Real lhs, Real rhs, Real eps=EPS) { return ABS(lhs-rhs) <= eps; }

constexpr bool EQ_EXACT(Real lhs, Real rhs) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
    return lhs == rhs;
#pragma GCC diagnostic pop
}

#define FOR(i, start, end) for(Int i = (start), CPP_CAT(i,xxxx_end)=(end); i < CPP_CAT(i,xxxx_end); ++i)
#define REP(i, n) FOR(i, 0, n)
#define LOOP(n) REP(CPP_CAT(macro_loop_counter,__COUNTER__), n)

#define ALL(f,c,...) (([&](decltype((c)) cccc) { return (f)(std::begin(cccc), std::end(cccc), ## __VA_ARGS__); })(c))
#define SLICE(f,c,l,r,...) (([&](decltype((c)) cccc, decltype((l)) llll, decltype((r)) rrrr) {\
    auto iiii = llll <= rrrr ? std::begin(cccc)+llll : std::end(cccc);\
    auto jjjj = llll <= rrrr ? std::begin(cccc)+rrrr : std::end(cccc);\
    return (f)(iiii, jjjj, ## __VA_ARGS__);\
})(c,l,r))

#define LIFT(f) ([](auto&&... args) -> decltype(auto) { return (f)(std::forward<decltype(args)>(args)...); })

template<class C>
constexpr Int SIZE(const C& c) noexcept { return Int(c.size()); }

template<class T, size_t N>
constexpr Int SIZE(const T (&)[N]) noexcept { return Int(N); }

constexpr bool is_odd (Int x) { return x%2 != 0; }
constexpr bool is_even(Int x) { return x%2 == 0; }
constexpr Int PARITY(Int x) { return x%2==0 ? 0 : 1; }

template<class T>
constexpr Int CMP(T x, T y) noexcept { return (y<x) - (x<y); }

template<class T>
constexpr Int SGN(T x) noexcept { return CMP(x,T(0)); }

template<class T1, class T2, class Comp=less<>,
         SFINAE(
             is_integral<T1>::value &&
             is_integral<T2>::value &&
             is_signed<T1>::value != is_unsigned<T2>::value
         )>
constexpr auto MAX(T1 x, T2 y, Comp comp={}) {
    return max<common_type_t<T1,T2>>({x,y}, comp);
}

template<class T1, class T2, class Comp=less<>,
         SFINAE(
             is_floating_point<T1>::value &&
             is_floating_point<T2>::value
         )>
constexpr auto MAX(T1 x, T2 y, Comp comp={}) {
    return max<common_type_t<T1,T2>>({x,y}, comp);
}

template<class T, class Comp=less<>>
constexpr const T& MAX(const T& x, const T& y, Comp comp={}) {
    return max(x, y, comp);
}

template<class T, class Comp=less<>>
constexpr T MAX(initializer_list<T> ilist, Comp comp={}) {
    return max(ilist, comp);
}

template<class T1, class T2, class Comp=less<>,
         SFINAE(
             is_integral<T1>::value &&
             is_integral<T2>::value &&
             is_signed<T1>::value != is_unsigned<T2>::value
         )>
constexpr auto MIN(T1 x, T2 y, Comp comp={}) {
    return min<common_type_t<T1,T2>>({x,y}, comp);
}

template<class T1, class T2, class Comp=less<>,
         SFINAE(
             is_floating_point<T1>::value &&
             is_floating_point<T2>::value
         )>
constexpr auto MIN(T1 x, T2 y, Comp comp={}) {
    return min<common_type_t<T1,T2>>({x,y}, comp);
}

template<class T, class Comp=less<>>
constexpr const T& MIN(const T& x, const T& y, Comp comp={}) {
    return min(x, y, comp);
}

template<class T, class Comp=less<>>
constexpr T MIN(initializer_list<T> ilist, Comp comp={}) {
    return min(ilist, comp);
}

template<class T, class U, class Comp=less<>>
constexpr bool chmax(T& xmax, const U& x, Comp comp={}) noexcept {
    if(comp(xmax, x)) {
        xmax = x;
        return true;
    }
    return false;
}

template<class T, class U, class Comp=less<>>
constexpr bool chmin(T& xmin, const U& x, Comp comp={}) noexcept {
    if(comp(x, xmin)) {
        xmin = x;
        return true;
    }
    return false;
}

template<class BinaryFunc, class UnaryFunc>
auto ON(BinaryFunc&& bf, UnaryFunc&& uf) {
    return [bf=forward<BinaryFunc>(bf),uf=forward<UnaryFunc>(uf)](const auto& x, const auto& y) {
        return bf(uf(x), uf(y));
    };
}

template<class F>
auto LT_ON(F&& f) {
    return ON(less<>{}, forward<F>(f));
}

template<class F>
auto GT_ON(F&& f) {
    return ON(greater<>{}, forward<F>(f));
}

template<class F>
auto NOT_FN(F&& f) {
    return [f=forward<F>(f)](auto&&... args) -> bool { return !f(forward<decltype(args)>(args)...); };
}

struct IDENTITY {
    using is_transparent = void;

    template<class T>
    constexpr decltype(auto) operator()(T&& x) const { return forward<T>(x); }
};

// ビット演算 {{{
// 引数は [-INF,INF] のみ想定
constexpr Int BIT_I(Int i) {
    return Int(1) << i;
}

constexpr Int BIT_I_1(Int i) {
    return BIT_I(i) - 1;
}

constexpr Int BIT_GET(Int x, Int i) {
    return x & BIT_I(i);
}

constexpr bool BIT_TEST(Int x, Int i) {
    return BIT_GET(x,i) != 0;
}

constexpr Int BIT_SET(Int x, Int i) {
    return x | BIT_I(i);
}

constexpr Int BIT_CLEAR(Int x, Int i) {
    return x & ~BIT_I(i);
}

constexpr Int BIT_FLIP(Int x, Int i) {
    return x ^ BIT_I(i);
}

constexpr Int BIT_ASSIGN(Int x, Int i, bool b) {
    return b ? BIT_SET(x,i) : BIT_CLEAR(x,i);
}

/*constexpr*/ Int BIT_COUNT_LEADING_ZEROS(Int x) {
    if(is_same<Int,i64>::value) return x==0 ? 64 : __builtin_clzll(u64(x));
    if(is_same<Int,i32>::value) return x==0 ? 32 : __builtin_clz(u32(x));
    ASSERT(false);
}

/*constexpr*/ Int BIT_COUNT_TRAILING_ZEROS(Int x) {
    if(is_same<Int,i64>::value) return x==0 ? 64 : __builtin_ctzll(u64(x));
    if(is_same<Int,i32>::value) return x==0 ? 32 : __builtin_clz(u32(x));
    ASSERT(false);
}

/*constexpr*/ Int BIT_COUNT_ONES(Int x) {
    if(is_same<Int,i64>::value) return __builtin_popcountll(u64(x));
    if(is_same<Int,i32>::value) return __builtin_popcount(u32(x));
    ASSERT(false);
}

// 1の個数が奇数なら1, 偶数なら0を返す
/*constexpr*/ Int BIT_PARITY(Int x) {
    if(is_same<Int,i64>::value) return __builtin_parityll(u64(x));
    if(is_same<Int,i32>::value) return __builtin_parity(u32(x));
    ASSERT(false);
}

// X ⊆ {0,1,...,n-1}, |X| = k なる部分集合 X を昇順に列挙する
// comb(n,k) 個
//
// ```
// Int x = BIT_I_1(3);
// do {
//     // ...
// } while(BIT_NEXT_SET_SIZED(x, 10));
// ```
/*constexpr*/ bool BIT_NEXT_SET_SIZED(Int& x, Int n) {
    if(x == 0) return false;
    Int t = (x|(x-1)) + 1;
    x = t | ((~t&(t-1)) >> (BIT_COUNT_TRAILING_ZEROS(x)+1));
    return x < BIT_I(n);
}

// 集合 Y の部分集合 X を昇順に列挙する
// 2^|Y| 個
//
// ```
// Int y = 0b10101;
// Int x = 0;
// do {
//     // ...
// } while(BIT_NEXT_SUBSET(x, y));
// ```
constexpr bool BIT_NEXT_SUBSET(Int& x, Int y) {
    if(x == y) return false;
    x = (x-y) & y;
    return true;
}

// 集合 Y の部分集合 X を降順に列挙する
// 2^|Y| 個
//
// ```
// Int y = 0b10101;
// Int x = y;
// do {
//     // ...
// } while(BIT_PREV_SUBSET(x, y));
// ```
constexpr bool BIT_PREV_SUBSET(Int& x, Int y) {
    if(x == 0) return false;
    x = (x-1) & y;
    return true;
}

// 集合 Y を包含する集合 X ⊆ {0,1,...,n-1} を昇順に列挙する
// 2^(n-|Y|) 個
//
// ```
// Int y = 0b00010101;
// Int x = y;
// do {
//     // ...
// } while(BIT_NEXT_SUPERSET(x, 8, y));
// ```
constexpr bool BIT_NEXT_SUPERSET(Int& x, Int n, Int y) {
    x = (x+1) | y;
    return x < BIT_I(n);
}
// }}}

// [lo,hi) 内で pred が真になる最大値を返す
// 全部NGの場合 lo-1 を返す
template<class Pred>
/*constexpr*/ Int bisect_integer(Int lo, Int hi, Pred pred) {
    ASSERT(lo < hi);
    if(!pred(lo)) return lo-1;

    while(lo+1 < hi) {
        Int mid = (lo+hi) / 2;
        if(pred(mid))
            lo = mid;
        else
            hi = mid;
    }
    return lo;
}

template<class Pred>
/*constexpr*/ Real bisect_real(Real lo, Real hi, Pred pred, Real eps=EPS) {
    ASSERT_LOCAL(!GT_EPS(lo,hi,eps));
    if(lo > hi) swap(lo, hi);

    while(!EQ_EPS(lo,hi,eps)) {
        Real mid = (lo+hi) / 2;
        if(pred(mid))
            lo = mid;
        else
            hi = mid;
    }
    return lo;
}

template<class Monoid>
/*constexpr*/ Monoid fastpow(const Monoid& x, Int e, const Monoid& unity) {
    ASSERT(e >= 0);
    if(e == 0) return unity;

    Monoid res = unity;
    Monoid cur = x;
    for(;;) {
        if(e & 1)
            res *= cur;
        e >>= 1;
        if(e == 0) break;
        cur *= cur;
    }
    return res;
}

/*constexpr*/ Int ipow(Int x, Int e) {
    return fastpow<Int>(x,e,1);
}

/*constexpr*/ Int sqrt_floor(Int x) {
    ASSERT(x >= 0);

    Int lo = 0;
    Int hi = MIN(x/2+2, SQRT_MAX<Int>()+1);
    return bisect_integer(lo, hi, [x](Int r) { return r*r <= x; });
}

/*constexpr*/ Int sqrt_ceil(Int x) {
    Int r = sqrt_floor(x);
    return r*r == x ? r : r+1;
}

/*constexpr*/ Int log2_ceil(Int x) {
    ASSERT(x > 0);
    if(is_same<Int,i64>::value) return 64 - BIT_COUNT_LEADING_ZEROS(x-1);
    if(is_same<Int,i32>::value) return 32 - BIT_COUNT_LEADING_ZEROS(x-1);
    ASSERT(false);
}

/*constexpr*/ Int log2_floor(Int x) {
    ASSERT(x > 0);
    if(is_same<Int,i64>::value) return 63 - BIT_COUNT_LEADING_ZEROS(x);
    if(is_same<Int,i32>::value) return 31 - BIT_COUNT_LEADING_ZEROS(x);
    ASSERT(false);
}

// x > 0
/*constexpr*/ Int pow2_ceil(Int x) {
    return BIT_I(log2_ceil(x));
}

// x > 0
/*constexpr*/ Int pow2_floor(Int x) {
    return BIT_I(log2_floor(x));
}

// Haskell の divMod と同じ
constexpr pair<Int,Int> divmod(Int a, Int b) {
    Int q = a / b;
    Int r = a % b;
    if((b>0 && r<0) || (b<0 && r>0)) {
        --q;
        r += b;
    }
    return {q,r};
}

constexpr Int div_ceil(Int a, Int b) {
    Int q = a / b;
    Int r = a % b;
    if((b>0 && r>0) || (b<0 && r<0))
        ++q;
    return q;
}

constexpr Int div_floor(Int a, Int b) {
    return divmod(a,b).first;
}

constexpr Int modulo(Int a, Int b) {
    return divmod(a,b).second;
}

/*constexpr*/ Int align_ceil(Int x, Int align) {
    ASSERT(align > 0);
    return div_ceil(x,align) * align;
}

/*constexpr*/ Int align_floor(Int x, Int align) {
    ASSERT(align > 0);
    return div_floor(x,align) * align;
}

template<class InputIt, class BinaryOp>
auto FOLD(InputIt first, InputIt last,
          typename iterator_traits<InputIt>::value_type init,
          BinaryOp op)
{
    for(; first != last; ++first)
        init = op(move(init), *first);
    return init;
}

template<class InputIt, class BinaryOp>
auto FOLD1(InputIt first, InputIt last, BinaryOp op) {
    auto init = *first++;
    return FOLD(first, last, init, op);
}

template<class InputIt>
auto SUM(InputIt first, InputIt last) {
    return FOLD1(first, last, plus<>{});
}

template<class C, class Pred>
void ERASE_IF(C& c, Pred pred) {
    c.erase(ALL(remove_if,c,pred), end(c));
}

template<class C>
void UNIQ(C& c) {
    c.erase(ALL(unique,c), end(c));
}

template<class C>
void SORT_UNIQ(C& c) {
    ALL(sort, c);
    UNIQ(c);
}

[[noreturn]] void EXIT() {
    cout.flush();
#ifdef PROCON_LOCAL
    cerr.flush();
    exit(0);
#else
    _Exit(0);
#endif
}

// tuple {{{
template<Int I=0, class F, class... TS, SFINAE(sizeof...(TS) == I)>
void tuple_enumerate(tuple<TS...>&, F&&) {}

template<Int I=0, class F, class... TS, SFINAE(sizeof...(TS) > I)>
void tuple_enumerate(tuple<TS...>& t, F&& f) {
    f(I, get<I>(t));
    tuple_enumerate<I+1>(t, forward<F>(f));
}

template<Int I=0, class F, class... TS, SFINAE(sizeof...(TS) == I)>
void tuple_enumerate(const tuple<TS...>&, F&&) {}

template<Int I=0, class F, class... TS, SFINAE(sizeof...(TS) > I)>
void tuple_enumerate(const tuple<TS...>& t, F&& f) {
    f(I, get<I>(t));
    tuple_enumerate<I+1>(t, forward<F>(f));
}
// }}}

// container {{{
template<class T> struct is_container : false_type {};
template<class T, size_t N> struct is_container<array<T,N>> : true_type {};
template<class... Args> struct is_container<vector<Args...>> : true_type {};
template<class... Args> struct is_container<deque<Args...>> : true_type {};
template<class... Args> struct is_container<list<Args...>> : true_type {};
template<class... Args> struct is_container<forward_list<Args...>> : true_type {};
template<class... Args> struct is_container<set<Args...>> : true_type {};
template<class... Args> struct is_container<multiset<Args...>> : true_type {};
template<class... Args> struct is_container<unordered_set<Args...>> : true_type {};
template<class... Args> struct is_container<unordered_multiset<Args...>> : true_type {};
template<class... Args> struct is_container<map<Args...>> : true_type {};
template<class... Args> struct is_container<multimap<Args...>> : true_type {};
template<class... Args> struct is_container<unordered_map<Args...>> : true_type {};
template<class... Args> struct is_container<unordered_multimap<Args...>> : true_type {};

template<class T, class Enable=void>
struct ProconHash {
    size_t operator()(const T& x) const noexcept {
        return hash<T>{}(x);
    }
};

template<class T>
size_t procon_hash_value(const T& x) noexcept {
    return ProconHash<T>{}(x);
}

size_t procon_hash_combine(size_t h1, size_t h2) noexcept {
    constexpr size_t M = UINT64_C(0xc6a4a7935bd1e995);
    constexpr int    R = 47;

    h2 *= M;
    h2 ^= h2 >> R;
    h2 *= M;

    h1 ^= h2;
    h1 *= M;

    h1 += 0xe6546b64;

    return h1;
}

template<class T1, class T2>
struct ProconHash<pair<T1,T2>> {
    size_t operator()(const pair<T1,T2>& p) const noexcept {
        size_t h1 = procon_hash_value(p.first);
        size_t h2 = procon_hash_value(p.second);
        return procon_hash_combine(h1, h2);
    }
};

template<class... TS>
struct ProconHash<tuple<TS...>> {
    size_t operator()(const tuple<TS...>& t) const noexcept {
        size_t h = 0;
        tuple_enumerate(t, [&h](Int, const auto& e) {
            h = procon_hash_combine(h, procon_hash_value(e));
        });
        return h;
    }
};

template<class C>
struct ProconHash<C,enable_if_t<is_container<C>::value>> {
    size_t operator()(const C& c) const noexcept {
        size_t h = 0;
        for(const auto& e : c)
            h = procon_hash_combine(h, procon_hash_value(e));
        return h;
    }
};

template<class T, class Hash=ProconHash<T>, class Eq=equal_to<T>>
using HashSet = unordered_set<T,Hash,Eq>;
template<class K, class V, class Hash=ProconHash<K>, class Eq=equal_to<K>>
using HashMap = unordered_map<K,V,Hash,Eq>;
template<class T, class Hash=ProconHash<T>, class Eq=equal_to<T>>
using HashMultiset = unordered_multiset<T,Hash,Eq>;
template<class K, class V, class Hash=ProconHash<K>, class Eq=equal_to<K>>
using HashMultimap = unordered_multimap<K,V,Hash,Eq>;

template<class T>
auto vec_make(Int n, T x) {
    return vector<T>(n, x);
}

template<class T, class... Args, SFINAE(sizeof...(Args) >= 2)>
auto vec_make(Int n, Args... args) {
    auto inner = vec_make<T>(args...);
    return vector<decltype(inner)>(n, inner);
}

template<class T>
auto vec_reserve(Int cap) {
    vector<T> res;
    res.reserve(cap);
    return res;
}

template<class T=Int>
auto vec_iota(Int n, T init={}) {
    vector<Int> res(n);
    ALL(iota, res, init);
    return res;
}

template<class ForwardIt, class BinaryOp>
auto vec_scan(ForwardIt first, ForwardIt last,
              typename iterator_traits<ForwardIt>::value_type init,
              BinaryOp op)
{
    using T = typename iterator_traits<ForwardIt>::value_type;
    auto res = vec_reserve<T>(distance(first,last)+1);
    res.emplace_back(init);
    for(; first != last; ++first) {
        init = op(move(init), *first);
        res.emplace_back(init);
    }
    return res;
}

template<class ForwardIt>
auto vec_cum(ForwardIt first, ForwardIt last) {
    using T = typename iterator_traits<ForwardIt>::value_type;
    return vec_scan(first, last, T{}, plus<>{});
}

template<class T, class Comp, class Cont=vector<T>>
auto priority_queue_make(const Comp& comp, Cont&& cont={}) {
    return priority_queue<T,remove_reference_t<Cont>,Comp>(comp, forward<Cont>(cont));
}

template<class T, class Comp>
auto priority_queue_reserve(const Comp& comp, Int cap) {
    return priority_queue<T,vector<T>,Comp>(comp, vec_reserve<T>(cap));
}

template<class T, size_t N, size_t... NS>
struct ArrayType {
    using type = array<class ArrayType<T,NS...>::type,N>;
};

template<class T, size_t N>
struct ArrayType<T,N> {
    using type = array<T,N>;
};

template<class T, size_t... NS>
using Array = typename ArrayType<T,NS...>::type;

template<class T, size_t N>
T& array_at(Array<T,N>& ary, Int i) {
    return ary[i];
}

template<class T, size_t N, size_t... NS, class... Args>
T& array_at(Array<T,N,NS...>& ary, Int i, Args... args) {
    return array_at<T,NS...>(ary[i], args...);
}

template<class T, size_t N>
const T& array_at(const Array<T,N>& ary, Int i) {
    return ary[i];
}

template<class T, size_t N, size_t... NS, class... Args>
const T& array_at(const Array<T,N,NS...>& ary, Int i, Args... args) {
    return array_at<T,NS...>(ary[i], args...);
}

template<class T, class C>
T POP(stack<T,C>& stk) {
    T x = stk.top(); stk.pop();
    return x;
}

template<class T, class C>
T POP(queue<T,C>& que) {
    T x = que.front(); que.pop();
    return x;
}

template<class T, class C, class Comp>
T POP(priority_queue<T,C,Comp>& que) {
    T x = que.top(); que.pop();
    return x;
}
// }}}

// fixpoint {{{
template<class F>
class FixPoint {
public:
    explicit constexpr FixPoint(F&& f) : f_(forward<F>(f)) {}

    template<class... Args>
    constexpr decltype(auto) operator()(Args&&... args) const {
        return f_(*this, forward<Args>(args)...);
    }

private:
    F f_;
};

template<class F>
constexpr decltype(auto) FIX(F&& f) {
    return FixPoint<F>(forward<F>(f));
}

template<class F, size_t... NS>
class FixPointMemo {
public:
    explicit FixPointMemo(F&& f) : f_(forward<F>(f)) {}

    template<class... Args>
    decltype(auto) operator()(Args... args) const {
        using R = decltype(f_(*this,args...));
        static Array<bool,NS...> done {};
        static Array<R,NS...>    memo;

        if(!array_at<bool,NS...>(done,args...)) {
            array_at<R,NS...>(memo,args...) = f_(*this,args...);
            array_at<bool,NS...>(done,args...) = true;
        }
        return array_at<R,NS...>(memo,args...);
    }

private:
    F f_;
};

template<size_t... NS, class F>
decltype(auto) FIXMEMO(F&& f) {
    return FixPointMemo<F,NS...>(forward<F>(f));
}
// }}}

// input {{{
template<class T>
struct Integral1 {
    static_assert(is_integral<T>::value && !is_same<T,bool>::value, "");
};
using Int1 = Integral1<Int>;

template<class T, class Enable=void>
struct Scan {
    using R = T;
    static R scan(istream& in) {
        R res;
        in >> res;
        return res;
    }
};

template<class T>
struct Scan<Integral1<T>> {
    using R = T;
    static R scan(istream& in) {
        return Scan<R>::scan(in) - 1;
    }
};

template<class T1, class T2>
struct Scan<pair<T1,T2>> {
    using R1 = typename Scan<T1>::R;
    using R2 = typename Scan<T2>::R;
    using R = pair<R1,R2>;
    static R scan(istream& in) {
        R1 x = Scan<T1>::scan(in);
        R2 y = Scan<T2>::scan(in);
        return {x,y};
    }
};

template<class T>
auto tuple_scan_impl(istream& in) {
    return make_tuple(Scan<T>::scan(in));
}

template<class T, class... TS, SFINAE(sizeof...(TS) > 0)>
auto tuple_scan_impl(istream& in) {
    auto head = make_tuple(Scan<T>::scan(in));
    return tuple_cat(head, tuple_scan_impl<TS...>(in));
}

template<class... TS>
struct Scan<tuple<TS...>> {
    using R = decltype(tuple_scan_impl<TS...>(cin));
    static R scan(istream& in) {
        return tuple_scan_impl<TS...>(in);
    }
};

template<class T=Int>
auto RD() {
    return Scan<T>::scan(cin);
}

template<class T=Int>
auto RD1() {
    return RD<Integral1<T>>();
}

template<class T=Int>
auto RD_VEC(Int n) {
    auto res = vec_reserve<typename Scan<T>::R>(n);
    LOOP(n) {
        res.emplace_back(RD<T>());
    }
    return res;
}

template<class T=Int>
auto RD1_VEC(Int n) {
    return RD_VEC<Integral1<T>>(n);
}

template<class T=Int>
auto RD_VEC2(Int h, Int w) {
    auto res = vec_reserve<vector<typename Scan<T>::R>>(h);
    LOOP(h) {
        res.emplace_back(RD_VEC<T>(w));
    }
    return res;
}

template<class T=Int>
auto RD1_VEC2(Int h, Int w) {
    return RD_VEC2<Integral1<T>>(h, w);
}
// }}}

// output {{{
template<class T, class Enable=void>
struct Fmt {
    static void fmt(ostream& out, const T& x) { out << x; }
};

template<class T>
void fmt_write(ostream& out, const T& x) {
    Fmt<T>::fmt(out, x);
}

template<class T>
string FMT_STR(const T& x) {
    ostringstream out;
    fmt_write(out, x);
    return out.str();
}

template<class... TS>
struct Fmt<tuple<TS...>> {
    static void fmt(ostream& out, const tuple<TS...>& t) {
        tuple_enumerate(t, [&out](Int i, const auto& e) {
            if(i != 0) out << ' ';
            fmt_write(out, e);
        });
    }
};

template<class T1, class T2>
struct Fmt<pair<T1,T2>> {
    static void fmt(ostream& out, const pair<T1,T2>& p) {
        return fmt_write(out, make_tuple(p.first,p.second));
    }
};

template<class C>
struct Fmt<C,enable_if_t<is_container<C>::value>> {
    static void fmt(ostream& out, const C& c) {
        for(auto it = begin(c); it != end(c); ++it) {
            if(it != begin(c)) out << ' ';
            fmt_write(out, *it);
        }
    }
};

void PRINT() {}

template<class T, class... TS>
void PRINT(const T& x, const TS&... args) {
    fmt_write(cout, x);
    if(sizeof...(args) > 0) {
        cout << ' ';
        PRINT(args...);
    }
}

template<class... TS>
void PRINTLN(const TS&... args) {
    PRINT(args...);
    cout << '\n';
}
// }}}

// init {{{
struct ProconInit {
    ProconInit() {
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
        cin.exceptions(ios::failbit | ios::badbit);
        cout << fixed << setprecision(COUT_PREC);
#ifdef PROCON_LOCAL
        cerr << fixed << setprecision(2);
#endif
        if(COUT_AUTOFLUSH)
            cout << unitbuf;
    }
} PROCON_INIT;
// }}}

// }}}

// SegTreeRQ {{{
template<class Monoid, class Action, class FuncMonoid, class FuncAction>
struct SegTreeRQ {
    FuncMonoid fm_;
    FuncAction fa_;
    Monoid unity_monoid_;
    Int n_;
    vector<Monoid> data_;

    SegTreeRQ(FuncMonoid&& fm, FuncAction&& fa, const Monoid& unity_monoid, Int n) :
        fm_(forward<FuncMonoid>(fm)), fa_(forward<FuncAction>(fa)), unity_monoid_(unity_monoid),
        n_(n==0?0:pow2_ceil(n)), data_(2*n_,unity_monoid_)
    {
        init_merge();
    }

    SegTreeRQ(FuncMonoid&& fm, FuncAction&& fa, const Monoid& unity_monoid, Int n, const Monoid& x) :
        fm_(forward<FuncMonoid>(fm)), fa_(forward<FuncAction>(fa)), unity_monoid_(unity_monoid),
        n_(n==0?0:pow2_ceil(n)), data_(2*n_,unity_monoid_)
    {
        fill_n(begin(data_)+n_, n, x);
        init_merge();
    }

    template<class ForwardIt>
    SegTreeRQ(FuncMonoid&& fm, FuncAction&& fa, const Monoid& unity_monoid, ForwardIt first, ForwardIt last) :
        fm_(forward<FuncMonoid>(fm)), fa_(forward<FuncAction>(fa)), unity_monoid_(unity_monoid),
        n_(first==last?0:pow2_ceil(distance(first,last))), data_(2*n_,unity_monoid_)
    {
        copy(first, last, begin(data_)+n_);
        init_merge();
    }

    void act(Int i, const Action& a) {
        Int v = i + n_;
        data_[v] = fa_(data_[v], a);
        while(v > 1) {
            v /= 2;
            data_[v] = fm_(data_[2*v], data_[2*v+1]);
        }
    }

    Monoid query(Int l, Int r) const {
        ASSERT_LOCAL(l <= r);
        return query_impl(l, r, 1, 0, n_);
    }

private:
    void init_merge() {
        for(Int v = n_-1; v >= 1; --v)
            data_[v] = fm_(data_[2*v], data_[2*v+1]);
    }

    Monoid query_impl(Int lq, Int rq, Int v, Int l, Int r) const {
        if(rq <= l || r <= lq) return unity_monoid_;

        if(lq <= l && r <= rq) return data_[v];

        Int mid = (l+r) / 2;
        Monoid ml = query_impl(lq, rq, 2*v,   l, mid);
        Monoid mr = query_impl(lq, rq, 2*v+1, mid, r);
        return fm_(ml, mr);
    }
};

template<class Monoid, class Action, class FuncMonoid, class FuncAction, class T>
auto segtree_rq_make(FuncMonoid&& fm, FuncAction&& fa, const T& unity_monoid, Int n) {
    return SegTreeRQ<Monoid,Action,FuncMonoid,FuncAction>(
        forward<FuncMonoid>(fm), forward<FuncAction>(fa), unity_monoid, n
    );
}

template<class Monoid, class Action, class FuncMonoid, class FuncAction, class T1, class T2>
auto segtree_rq_make(FuncMonoid&& fm, FuncAction&& fa, const T1& unity_monoid, Int n, const T2& x) {
    return SegTreeRQ<Monoid,Action,FuncMonoid,FuncAction>(
        forward<FuncMonoid>(fm), forward<FuncAction>(fa), unity_monoid, n, x
    );
}

template<class Monoid, class Action, class FuncMonoid, class FuncAction, class T, class ForwardIt>
auto segtree_rq_range(FuncMonoid&& fm, FuncAction&& fa, const T& unity_monoid, ForwardIt first, ForwardIt last) {
    return SegTreeRQ<Monoid,Action,FuncMonoid,FuncAction>(
        forward<FuncMonoid>(fm), forward<FuncAction>(fa), unity_monoid, first, last
    );
}
// }}}

//--------------------------------------------------------------------

void solve() {
    Int N = RD();
    auto A = RD_VEC(N);

    auto is = vec_iota(N);
    ALL(sort, is, LT_ON([&A](Int i) { return make_pair(A[i],-i); }));

    using Monoid = pair<Int,Int>;  // (len,sum)
    using Action = pair<Int,Int>;
    auto seg = segtree_rq_make<Monoid,Action>(
        LIFT(MAX),
        [](const Monoid&, const Action& a) -> Monoid { return a; },
        make_pair(0,0),
        N
    );

    for(Int i : is) {
        Int a = A[i];
        auto m = seg.query(0, i);
        ++m.first;
        m.second += a;
        seg.act(i, m);
    }

    auto m = seg.query(0, N);
    Int ans = m.second;

    PRINTLN(ans);
}

signed main() {
    solve();
    EXIT();
}
accuracy: 1
time_ms: 30
memory_kb: 8628
final_rank: 7

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

int n, a[Maxn], f[Maxn], Lngst, nxt[Maxn];


int main()
{
    scanf("%d", &n);
    for (int i=1; i<=n; i++)
    {
        scanf("%d", &a[n - i + 1]);
        f[i] = -1;
    }
    for (int i=1; i<=n; i++)
    {
        nxt[i] = lower_bound(f, f + n, a[i], greater<int>()) - f;
        f[nxt[i]] = a[i];
        Lngst = max(Lngst, nxt[i]);
    }
    
    long long Res = 0;
    for (int i=n; i>=1; i--)
        if (nxt[i] == Lngst) { Res+=a[i]; Lngst--; }
    
    printf("%lld\n", Res);
}
accuracy: 1
time_ms: 10
memory_kb: 4388
final_rank: 1

code_snippet: #include "bits/stdc++.h"
#include<vector>
#include<iostream>
#include<queue>
#include<algorithm>
#include<map>
#include<set>
#include<iomanip>
#include<assert.h>
#include<unordered_map>
#include<unordered_set>
#include<string>
#include<stack>
#include<complex>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class T>
using Table = vector<vector<T>>;
const ld eps=1e-9;
	
#define WHATS(var)cout<<__LINE__<<' '<<#var<<"="<<var<<endl;
	
template<class S, class T> ostream& operator <<(ostream &os, const pair<S, T> v){
	os << "( " << v.first << ", " << v.second << ")"; return os;
}
template<class T> ostream& operator <<(ostream &os, const vector<T> &v){
	for(int i = 0; i < v.size(); i++){if(i > 0){os << " ";} os << v[i];} return os;
}
template<class T> ostream& operator <<(ostream &os, const vector<vector<T>> &v){
	for(int i = 0; i < v.size(); i++){if(i > 0){os << endl;} os << v[i];} return os;
}
template<class T> ostream& operator <<(ostream &os, const vector<set<T>> &v){
	for(int i = 0; i < v.size(); i++){if(i > 0){os << endl;} os << v[i];} return os;
}
template<class T> ostream& operator <<(ostream &os, const set<T> &v){
	int i=0;
	for(auto it:v){
		if(i > 0){os << ' ';}
		os << it;
		i++;
	} 
	return os;
}

using ll =long long ;
ll mod;

void solve(vector<vector<int>>&cango){
	int tt=cango.size();
	for(int i=0;i<tt;++i){
		for(int j=0;j<tt;++j){
			for(int k=0;k<tt;++k){
				cango[j][k]|=cango[j][i]&cango[i][k];
			}
		}
	}
}
vector<int> dfs(int now,int N,vector<pair<int,int>>&edges){
	vector<int>av{now};
	if(now*2+1<N){
		auto v=dfs(now*2+1,N,edges);
		av.insert(av.end(),v.begin(),v.end());
	}
	if(now*2+2<N){
		auto v=dfs(now*2+2,N,edges);
		for(auto e:v){
			edges.push_back(make_pair(now,e));
		}
		av.insert(av.end(),v.begin(),v.end());
	}
	return av;
}

int ask(int x){
	cout<<x+1<<endl;
	fflush(stdout);
	string st;cin>>st;
	if(st=="Yes")return -1;
	else if(st=="No")return 0;
	else return 1;
}
int main() {
	ios::sync_with_stdio(false);
	int N;cin>>N;
	vector<int>v(N);
	for(int i=0;i<N;++i)cin>>v[i];
	reverse(v.begin(),v.end());
	for(int i=0;i<v.size();++i){
		v[i]=1e5-v[i];
	}
	vector<pair<int,ll>>vs(N+1,make_pair(1e9,0));
	for(int i=0;i<N;++i){
		auto it=lower_bound(vs.begin(),vs.end(),make_pair(v[i],ll(-1)));
		if(it==vs.begin()){
			vs[0]=make_pair(v[i],v[i]);
		}else{
			auto p=*prev(it);
			vs[it-vs.begin()]=make_pair(v[i],p.second+v[i]);
		}
	}
	for(int i=N;i>=0;--i){
		if(vs[i].first!=1e9){
			cout<<ll(100000)*(i+1)-vs[i].second<<endl;
			break;
		}
	}
	
	return 0;	
}
accuracy: 1
time_ms: 10
memory_kb: 4684
final_rank: 2

code_snippet: #include <algorithm>
#include <iostream>
#include <vector>
#include <functional>
using namespace std;

template<typename Monoid>
struct SegmentTree {
    using F = function<Monoid(Monoid, Monoid)>;
    const F f;
    const Monoid M1;
    int sz;
    vector<Monoid> dat;
    SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
        sz = 1;
        while (sz < n) sz <<= 1;
        dat.assign(sz * 2, M1);
    }
    void set(int k, const Monoid &x) { dat[k + sz] = x; }
    void build() {
        for (int k = sz - 1; k > 0; k--) {
            dat[k] = f(dat[2 * k], dat[2 * k + 1]);
        }
    }
    void update(int k, const Monoid &x) {
        dat[k += sz] = x;
        while (k >>= 1) dat[k] = f(dat[2 * k], dat[2 * k + 1]);
    }
    Monoid get(int a, int b) {  // [a, b)
        Monoid L = M1, R = M1;
        for (a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
            if (a & 1) L = f(L, dat[a++]);
            if (b & 1) R = f(dat[--b], R);
        }
        return f(L, R);
    }
    Monoid operator[](const int &k) const { return dat[k + sz]; }
    friend ostream& operator<<(ostream& os, SegmentTree<Monoid> &seg) {
        for (int i = 0; i < seg.sz; i++) os << seg[i] << " ";
        return os;
    }
};

int main() {
    const int MAX = 1e5;
    int n; cin >> n;
    vector<int> a(n);
    for (int &ai: a) cin >> ai;
    using P = pair<int, long long>;
    auto f = [](const P &a, const P &b) { return max(a, b); };
    SegmentTree<P> seg(MAX + 1, f, {0, 0});
    for (int ai: a) {
        auto p = seg.get(0, ai);
        seg.update(ai, max(seg[ai], {p.first + 1, p.second + ai}));
    }
    cout << seg.get(0, MAX + 1).second << endl;
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 7336
final_rank: 8

code_snippet: /*  -*- coding: utf-8 -*-
 *
 * 2941.cc: LISum
 */

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_N = 100000;

/* typedef */

typedef long long ll;

/* global variables */

int as[MAX_N], dp[MAX_N], ids[MAX_N], bs[MAX_N];

/* subroutines */

int lds(int n, int as[], int bs[]) { // longest decleasing sequence
  fill(dp, dp + n, -1);

  int m = 0;
  for (int i = 0; i < n; ++i) {
    ids[i] = lower_bound(dp, dp + n, as[i], greater<int>()) - dp;
    dp[ids[i]] = as[i];
    if (m < ids[i]) m = ids[i];
  }
  //for (int i = 0; i < n; i++) printf("%d ", ids[i]); putchar('\n');
  //for (int i = 0; i <= m; i++) printf("%d ", dp[i]); putchar('\n');

  int bn = m + 1;

  for (int i = n - 1; i >= 0; --i)
    if (ids[i] == m) bs[m--] = as[i];

  return bn;
}

/* main */

int main() {
  int n;
  scanf("%d", &n);
  for (int i = n - 1; i >= 0; i--) scanf("%d", as + i);

  int m = lds(n, as, bs);

  ll sum = 0;
  for (int i = 0; i < m; i++) sum += bs[i];
  printf("%lld\n", sum);

  //for (int i = 0; i < m; i++) printf("%d ", bs[i]); putchar('\n');
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4708
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

template <typename Monoid>
struct SegmentTree{
private:
    using F = function<Monoid(Monoid, Monoid)>;
    int N;
    vector<Monoid> node;
    F f;
    Monoid e;  // identity element

public:
    SegmentTree(){}
    SegmentTree(F f, Monoid e):f(f), e(e){}
    void init(int sz){
        N = 1;
        while(N < sz) N <<= 1;
        node.assign(2*N-1, e);
    }
    void build(vector<Monoid>& v){
        int sz = int(v.size());
        init(sz);
        for(int i=0; i<sz; i++){
            node[i+N-1] = v[i];
        }
        for(int i=N-2; i>=0; i--){
            node[i] = f(node[i*2+1], node[i*2+2]);
        }
    }
    void update(int k, Monoid x){
        k += N-1;
        node[k] = x;
        while(k > 0){
            k = (k-1)/2;
            node[k] = f(node[2*k+1], node[2*k+2]);
        }
    }
    // [a,b)
    Monoid query(int a, int b){return query(a, b, 0, 0, N);}
    Monoid query(int a, int b, int k, int l, int r){
        if(b <= l || r <= a) return e;
        if(a <= l && r <= b) return node[k];
        Monoid vl, vr;
        vl = query(a, b, 2*k+1, l, (l+r)/2);
        vr = query(a, b, 2*k+2, (l+r)/2, r);
        return f(vl, vr);
    }
};

auto f = [&](P a, P b){return max(a,b);};
SegmentTree<P> seg(f,P(0,0));

int main() {
    ll n;
    cin >> n;
    vector<P> a(n);
    for(int i=0;i<n;i++){
        cin >> a[i].first;
        a[i].second = -i;
    }
    sort(a.begin(), a.end());
    seg.init(n);
    ll len = 0, ans = 0;
    for(int i=0;i<n;i++){
        // (len, sum)
        P p = seg.query(0,abs(a[i].second));
        p.first++;
        p.second += a[i].first;
        seg.update(abs(a[i].second), p);
        if(p.first > len){
            len = p.first;
            ans = p.second;
        }
        else if (p.first == len){
            ans = max(ans, p.second);
        }
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 8392
final_rank: 13

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

void chmax(int64_t& a, int64_t b){
    a = max(a, b);
}

int main(){
    int N, A[100000];
    cin >> N;
    for(int i=0; i<N; i++) cin >> A[i];

    vector<int> dp(N, 1e9), dp2(N);
    for(int i=0; i<N; i++){
        int pos = lower_bound(dp.begin(), dp.end(), A[i]) - dp.begin();
        dp[pos] = A[i];
        dp2[i] = pos;
    }
    int L = *max_element(dp2.begin(), dp2.end()) + 1;

    map<int, int64_t> sum[100001];
    sum[0][0] = 0;
    for(int i=0; i<N; i++){
        int l = dp2[i];
        int64_t prv = prev(sum[l].lower_bound(A[i]))->second;
        sum[l+1][A[i]] = prv + A[i];
    }
    int64_t ans = sum[L].rbegin()->second;
    cout << ans << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 14968
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i))
#define all(x) (x).begin(),(x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout<<#x" = "<<((x))<<endl
template<class T,class U> ostream& operator<<(ostream& o, const pair<T,U> &p){o<<"("<<p.fi<<","<<p.se<<")";return o;}
template<class T> ostream& operator<<(ostream& o, const vector<T> &v){o<<"[";for(T t:v){o<<t<<",";}o<<"]";return o;}

const int INF = 1010101;

struct MaxSegTree{
    int n; vector<ll> dat;
    // 初期化
    MaxSegTree(int _n){
        n=1;
        while(n<_n) n*=2;
        dat=vector<ll>(2*n-1,0);
    }
    // k番目(0-indexed)の値をaに変更
    void update(int k, ll a){
        k+=n-1;
        dat[k]=a;
        //更新
        while(k>0){
            k=(k-1)/2;
            dat[k]=max(dat[2*k+1],dat[2*k+2]);
        }
    }
    // 内部的に投げられるクエリ
    ll _query(int a, int b, int k, int l, int r){
        if(r<=a || b<=l) return 0;
        if(a<=l && r<=b) return dat[k];

        ll vl=_query(a,b,2*k+1,l,(l+r)/2);
        ll vr=_query(a,b,2*k+2,(l+r)/2,r);
        return max(vl,vr);
    }
    // [a,b)
    ll query(int a, int b){
        return _query(a,b,0,0,n);
    }
};

using pi = pair<int,int>;

int main(){
    int n;
    scanf(" %d", &n);
    vector<int> a(n);
    rep(i,n) scanf(" %d", &a[i]);

    vector<int> x(n);
    vector<int> dp(n+2, INF);
    dp[0] = -1;
    rep(i,n){
        int idx = lower_bound(all(dp), a[i]) - dp.begin();
        dp[idx] = a[i];
        x[i] = idx;
    }

    int L = 0;
    while(dp[L]<INF) ++L;
    --L;

    vector<vector<int>> v(L+1);
    rep(i,n) v[x[i]].pb(i);

    MaxSegTree st(n);

    unordered_map<int,ll> pre;
    rep(i,n)if(x[i]==1) pre[i] = a[i];
    for(int i=2; i<=L; ++i){
        vector<pi> p;
        for(int j:v[i-1]) p.pb({a[j],j});
        sort(all(p));

        int P = p.size();
        int pidx = 0;

        vector<pi> now;
        unordered_map<int,ll> nx;
        for(int j:v[i]) now.pb({a[j],j});
        sort(all(now));

        for(const auto &pp:now){
            int idx = pp.se;
            while(pidx<P && p[pidx].fi<pp.fi){
                st.update(p[pidx].se, pre[p[pidx].se]);
                ++pidx;
            }

            ll val = st.query(0,idx);
            nx[idx] = val+a[idx];
        }

        for(const auto &pp:p) st.update(pp.se, 0);

        pre = nx;
    }

    ll ans = 0;
    for(const auto &pp:pre) ans = max(ans, pp.se);
    printf("%lld\n", ans);
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 11500
final_rank: 14