Submission #1352261

#TimeUsernameProblemLanguageResultExecution timeMemory
1352261cig32Teleporter 2 (JOI26_teleporter)C++20
100 / 100
1850 ms19216 KiB
#include "bits/stdc++.h"
#define int long long 
#define vi vector<int>
#define pb push_back
#define pii pair<int, int>
using namespace std;

const int MAXN = 1e5 + 10;

int n, m, k;
int s[MAXN], t[MAXN], c[MAXN];
vi fr[MAXN];

struct Node {
  int lazy = 0;
  int mn = 0, mnidx;
} seg[4 * MAXN];

void init(int l, int r, int idx) {
  seg[idx].mnidx = l;
  seg[idx].mn = seg[idx].lazy = 0;
  if (l == r) {
    return;
  }
  int mid = (l + r) >> 1;
  init(l, mid, 2 * idx + 1);
  init(mid + 1, r, 2 * idx + 2);
}

void push_down(int idx) {
  if (!seg[idx].lazy) return;
  for (int i=(idx<<1) + 1; i<=(idx<<1) + 2; i++) {
    seg[i].lazy += seg[idx].lazy;
    seg[i].mn += seg[idx].lazy;
  }
  seg[idx].lazy = 0;
}

void push_up(int idx) {
  seg[idx].mn = min(seg[(idx<<1) + 1].mn, seg[(idx<<1) + 2].mn);
  seg[idx].mnidx = (
    seg[idx].mn == seg[(idx<<1) + 1].mn ? 
    seg[(idx<<1) + 1].mnidx : seg[(idx<<1) + 2].mnidx
  );
}

void u(int l, int r, int constl, int constr, int idx, int val) {
  if (l <= constl && constr <= r) {
    seg[idx].lazy += val;
    seg[idx].mn += val;
    return;
  }
  push_down(idx);
  int mid = (constl + constr) >> 1;
  if (mid < l || r < constl) u(l, r, mid+1, constr, (idx<<1) + 2, val);
  else if (constr < l || r < mid+1) u(l,r , constl, mid, (idx<<1) + 1, val);
  else {
    u(l, r, constl, mid, (idx<<1) + 1, val);
    u(l, r, mid+1, constr, (idx<<1) + 2, val);
  }
  push_up(idx);
}

pii qu(int l, int r, int constl, int constr, int idx) {
  if (l <= constl && constr <= r) return {seg[idx].mn, seg[idx].mnidx};
  int mid = (constl + constr) >> 1;
  push_down(idx);
  if (mid < l || r < constl) return qu(l, r, mid+1, constr, (idx<<1) + 2);
  else if (constr < l || r < mid+1) return qu(l, r, constl, mid, (idx<<1) + 1);
  else {
    return 
    min(
      qu(l, r, constl, mid, (idx<<1) + 1),
      qu(l, r, mid+1, constr, (idx<<1) + 2)
    );
  }
}

void range_add(int l, int r, int v) {
  u(l, r, 0, n, 0, v);
}

pii query(int l, int r) {
  return qu(l, r, 0, n, 0);
}

pii min_intercept(int slope) {
  pii dp[n+1];
  dp[0] = {0, 0};
  init(0, n, 0);
  for (int i=1; i<=n; i++) {
    pii bruh = query(0, i - 1);
    int res = bruh.first, idx = bruh.second;
    dp[i] = {res - slope, dp[idx].second + 1};
    range_add(i, i, dp[i].first);
    for (int x: fr[i]) {
      range_add(0, s[x], c[x]);
    }
  }
  return dp[n];
}

void solve() {
  cin >> n >> m >> k;
  for (int i=1; i<=n; i++) fr[i].clear();
  for (int i=1; i<=m; i++) {
    cin >> s[i] >> t[i] >> c[i];
    fr[t[i]].pb(i);
  }
  m++;
  n++;
  k++;
  s[m] = t[m] = n;
  c[m] = 1e18;
  
  int lb = -1e14, rb = -1;
  while (lb < rb) {
    int mid = lb + ((rb - lb + 1) >> 1);
    if (min_intercept(mid).second > k) rb = mid - 1;
    else lb = mid;
  }
  pii fin = min_intercept(lb);
  cout << max(0ll, fin.first + k * lb) << "\n";
}

int32_t main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int t = 1;
  // cin >> t;
  for (int i=1; i<=t; i++) solve();
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...