QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#418665#8718. 保区间最小值一次回归问题wsyearWA 873ms122084kbC++172.8kb2024-05-23 15:03:372024-05-23 15:05:21

Judging History

你现在查看的是最新测评结果

  • [2024-05-23 15:05:21]
  • 管理员手动重测该提交记录
  • 测评结果:WA
  • 用时:873ms
  • 内存:122084kb
  • [2024-05-23 15:03:37]
  • 提交

answer

#include <bits/stdc++.h>

#define rep(i, j, k) for (int i = (j); i <= (k); ++i)
#define per(i, j, k) for (int i = (j); i >= (k); --i)
#define SZ(v) int((v).size())
#define ALL(v) (v).begin(),(v).end()
#define fi first
#define se second
using ll = long long;
using pii = std::pair<int, int>;
using pll = std::pair<ll, ll>;

template<class T>inline void chkmn(T &x, T y) { if (y < x) x = y; }
template<class T>inline void chkmx(T &x, T y) { if (y > x) x = y; }

using namespace std;

const int maxn = 500010;
const int inf = 2e9;

int n, m, tot, a[maxn], mx[maxn], st[maxn][20], c[maxn], tlim[maxn], val[maxn];
ll dp[maxn];
vector<int> mvec[maxn], pos[maxn];
vector<pii> vec[maxn];
tuple<int, int, int> lim[maxn];
multiset<int> S;

int que(int l, int r) {
  int k = __lg(r - l + 1);
  return min(st[l][k], st[r - (1 << k) + 1][k]);
}

void work() {
  cin >> n >> m;
  rep (i, 1, n) cin >> a[i];
  rep (i, 1, n) mvec[i].clear();
  rep (i, 1, m) {
    int l, r, v;
    cin >> l >> r >> v, c[i] = v;
    mvec[l].emplace_back(v);
    mvec[r + 1].emplace_back(-v);
    lim[i] = make_tuple(l, r, v);
  }
  S.clear();
  rep (i, 1, n) {
    for (int x : mvec[i]) {
      if (x > 0) S.emplace(x);
      else S.erase(S.find(-x));
    }
    if (S.empty()) mx[i] = st[i][0] = inf;
    else mx[i] = st[i][0] = *prev(S.end());
  }
  rep (j, 1, 19) rep (i, 1, n - (1 << j) + 1) {
    st[i][j] = min(st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
  }
  rep (i, 1, m) {
    auto [l, r, v] = lim[i];
    if (que(l, r) != v) return cout << "-1\n", void();
  }
  sort(c + 1, c + m + 1), tot = unique(c + 1, c + m + 1) - c - 1;
  rep (i, 1, tot) vec[i].clear(), pos[i].clear();
  ll ans = 0;
  rep (i, 1, n) if (mx[i] != inf) {
    if (a[i] < mx[i]) ans += mx[i] - a[i], a[i] = mx[i];
    int w = lower_bound(c + 1, c + tot + 1, mx[i]) - c;
    pos[w].emplace_back(i);
  }
  rep (i, 1, m) {
    auto [l, r, v] = lim[i];
    v = lower_bound(c + 1, c + tot + 1, v) - c;
    vec[v].emplace_back(l, r);
  }
  rep (i, 1, tot) if (SZ(vec[i])) {
    int w = SZ(pos[i]);
    rep (j, 1, w) val[j] = a[pos[i][j - 1]] - c[i];
    val[w + 1] = 0;
    rep (j, 1, w + 1) tlim[i] = 0;
    for (auto &[l, r] : vec[i]) {
      l = lower_bound(ALL(pos[i]), l) - pos[i].begin() + 1;
      r = upper_bound(ALL(pos[i]), r) - pos[i].begin();
      chkmx(tlim[r + 1], l);
    }
    rep (j, 1, w + 1) chkmx(tlim[j], tlim[j - 1]);
    rep (j, 1, w + 1) dp[i] = 1e18;
    multiset<ll> S;
    int pos = 0;
    S.emplace(0);
    rep (j, 1, w + 1) {
      while (pos < tlim[j]) {
        S.erase(S.find(dp[pos]));
        pos++;
      }
      dp[j] = *S.begin() + val[j];
      S.emplace(dp[j]);
    }
    ans += dp[w + 1];
  }
  cout << ans << '\n';
}

int main() {
  cin.tie(nullptr) -> ios::sync_with_stdio(false);
  int t; cin >> t;
  while (t--) work();
}

详细

Test #1:

score: 100
Accepted
time: 4ms
memory: 52660kb

input:

1
3 2
2023 40 41
1 1 2022
2 3 39

output:

2

result:

ok 1 number(s): "2"

Test #2:

score: -100
Wrong Answer
time: 873ms
memory: 122084kb

input:

1000
100 100
1 35141686 84105222 84105220 7273527 178494861 178494861 112519027 77833654 77833656 261586535 278472336 278472336 261586536 416361017 416361017 426649080 323519513 278472337 420127821 420127823 420127823 482516531 434108818 420127821 631535744 615930922 546346921 546346920 546346920 70...

output:

59
55
46
56
56
50
56
55
53
58
55
63
1077
63
56
64
55
71
57
48
53
61
49
62
54
64
55
47
50
50
46
59
62
56
66
52
50
46
47
56
50
54
50
54
957
1080
57
60
54
59
56
50
61
58
46
51
64
62
64
55
43
56
48
46
61
47
57
51
42
60
66
54
51
49
51
54
45
53
47
52
50
42
54
51
56
52
53
51
45
50
56
47
52
59
50
48
49
52
5...

result:

wrong answer 1st numbers differ - expected: '49', found: '59'