http://codeforces.com/contest/777/problem/E
内周の半径を$a_i$,外周の半径を$b_i$,高さを$h_i$とした輪っかがある.$i$番目の上に$j$番目が乗ることができる条件は$b_j \leq b_i$かつ,$b_j > a_i$である.内周の半径より,上に乗せようと考えている外周の半径が小さい場合は,重ねることができない.高さの合計の最大値を求めよ.
まず条件より外周が大きい順,さらに外周が同じ場合は内周が大きい順にsortすると良さそう.stackで現在乗せているものを表す.stackのtopと$i$番目を比較して,乗る状態であるならば乗せる.そうでないならば,乗せられる状態になるまでstackをpopする.このようにすることで,以前の高さの和を持っておくことができ,乗せられないものが出ても対応できる.
#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define REP(i,k,n) for(int i=k;i<(int)(n);i++)
#define each(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++)
#define INF 1<<30
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef pair<P, int> PI;
int main() {
int n;
cin >> n;
vector<PI> v(n);
rep(i, n) cin >> v[i].fi.se >> v[i].fi.fi >> v[i].se;
sort(v.begin(), v.end(), greater<PI>());
ll ans = 0, sum = 0;
stack<PI> st;
rep(i, n) {
while(st.size()) {
PI p = st.top();
if(v[i].fi.fi <= p.fi.fi && v[i].fi.fi > p.fi.se) break;
sum -= p.se;
st.pop();
}
sum += v[i].se;
st.push(v[i]);
ans = max(ans, sum);
}
cout << ans << endl;
return 0;
}