競技プログラミング日記

主に AtCoder の記事です

AtCoder Beginner Contest 017C

C - ハイスコア

0-indexed で考える.
 i \in N i \in \{0, 1, \cdots, N-1\}を表す.

imos法
区間 i に対して得点 s_{i} が対応している.
もし 0から M-1までの全ての値を,選んだ区間で覆うと得点は0.
また,0点より大きい得点が欲しければ,一か所でも覆えていなければよい.この場合,選んだ区間 i s_{i}たちの和が得点として入る.
よって,どこで途切れるかを場合分けして全探索.

 i \in Mを途切れさせるとすれば, iを含まない区間は全て使うのが最善.
また,
(  iを覆わない区間全体 ) = (  i \in N区間 ) - ( iを覆う区間全体)
となるので, s_{i}たちの和も同様の等式が成り立つ.

(  i \in N区間 )の s_{i}の和は前計算で O(N)
(  iを覆う区間全体 )の s_{i}の和はimos 法で O(M)

 

typedef long long ll;
using vll = vector<long long>;  using vvll = vector<vll>;
#define srep(i,s,t) for (ll i = (s); i < (t); ++i)
#define rep(i,n) srep(i,0,(n))
#define all(x) (x).begin(),(x).end()
template<class T>bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }

int main() {
    ll n, m, k, q;
    cin >> n >> m;

    vll ev(m+10);
    ll t = 0;
    rep(i,n){
        ll l,r,s; cin >> l >> r >> s;
        --l, --r;
        r++;

        ev[l] += s;
        ev[r] -= s;
        t += s;
    }

    vll imos(m+10);
    ll sum = 0;
    rep(i,m+10){
        sum += ev[i];
        imos[i] = sum;
    }
    assert(sum == 0);

    ll ans = 0;
    rep(i,m){
        chmax(ans, t - imos[i]);
    }
    cout << ans << endl;

    return 0;
}