QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#441324#5094. 小 H 分糖果james1BadCreeper0 0ms0kbC++174.0kb2024-06-14 14:28:562024-06-14 14:28:58

Judging History

This is the latest submission verdict.

  • [2024-06-14 14:28:58]
  • Judged
  • Verdict: 0
  • Time: 0ms
  • Memory: 0kb
  • [2024-06-14 14:28:56]
  • Submitted

answer

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef __int128 i128;
ostream& operator<<(ostream& out, i128 x) {
  if (x < 0)
    out << "-", x = -x;
  else if (!x)
    return out << '0';
  char tmp[40];
  int t = 0;
  while (x) tmp[t++] = x % 10 | '0', x /= 10;
  while (t) out << tmp[--t];
  return out;
}
constexpr int N = 1e5 + 9, B = 60, M = N * 40, A = 1e9;
struct {
  int l, r, c;
  ll s;
  i128 s2;
} tr[M << 1];
int n, q, a[N], rt[N], bit[N], tot;
int fa[N], dfn[N], ed[N], sz[N], sn[N], top[N];
i128 sum;
vector<int> es[N];
void dfs1(int x) {
  sz[x] = 1;
  for (int y : es[x]) {
    es[y].erase(remove(es[y].begin(), es[y].end(), x), es[y].end());
    fa[y] = x, dfs1(y), sz[x] += sz[y];
    if (sz[y] > sz[sn[x]]) sn[x] = y;
  }
}
void dfs2(int x, int t) {
  static int dt;
  dfn[x] = ++dt;
  top[x] = t;
  if (int z = sn[x]) {
    dfs2(z, t);
    for (int y : es[x])
      if (y != z) dfs2(y, y);
  }
  ed[x] = dt;
}
void add(int& x, int p, int v, int L, int R) {
  tr[++tot] = tr[x], x = tot;
  tr[x].c += v, tr[x].s += v * p, tr[x].s2 += 1ll * v * p * p;
  if (L == R) return;
  int mid = (L + R) >> 1;
  if (p <= mid)
    add(tr[x].l, p, v, L, mid);
  else
    add(tr[x].r, p, v, mid + 1, R);
}
void addb(int& x, int p, int v, int L, int R) {
  if (!x) tr[x = ++tot] = {0, 0, 0, 0, 0};
  tr[x].c += v, tr[x].s += v * p, tr[x].s2 += 1ll * v * p * p;
  if (L == R) return;
  int mid = (L + R) >> 1;
  if (p <= mid)
    addb(tr[x].l, p, v, L, mid);
  else
    addb(tr[x].r, p, v, mid + 1, R);
}
void dfs3(int x) {
  add(rt[x] = rt[fa[x]], a[x], 1, 0, A);
  for (int y : es[x]) dfs3(y);
}
void rebuild() { tot = 0, dfs3(1), memset(bit + 1, 0, n * sizeof(int)); }
int lca(int u, int v) {
  while (top[u] != top[v])
    if (sz[top[u]] < sz[top[v]])
      u = fa[top[u]];
    else
      v = fa[top[v]];
  return sz[u] > sz[v] ? u : v;
}
void upd(int x, int v) {
  static int cnt;
  int l = dfn[x], r = ed[x] + 1, y = exchange(a[x], v);
  sum += 1ll * (v + y) * (v - y);
  while (l <= n)
    addb(bit[l], y, -1, 0, A), addb(bit[l], v, 1, 0, A), l += l & -l;
  while (r <= n)
    addb(bit[r], y, 1, 0, A), addb(bit[r], v, -1, 0, A), r += r & -r;
  if (++cnt == N / B) rebuild(), cnt = 0;
}
void qry(int x, int d, vector<pair<int, int>>& res) {
  if (rt[x]) res.emplace_back(rt[x], d);
  for (x = dfn[x]; x; x &= x - 1)
    if (bit[x]) res.emplace_back(bit[x], d);
}
signed main() {
  freopen("PanzerSupply.in", "r", stdin);
  freopen("PanzerSupply.out", "w", stdout);
  cin.tie(nullptr)->sync_with_stdio(false);
  cin >> n >> q;
  for (int i = 1, u, v; i < n; ++i)
    cin >> u >> v, es[u].push_back(v), es[v].push_back(u);
  dfs1(1), dfs2(1, 1);
  for (int i = 1; i <= n; ++i) cin >> a[i], sum += 1ll * a[i] * a[i];
  dfs3(1);
  for (int op, u, v; q; --q)
    if (cin >> op >> u >> v, op == 1)
      upd(u, v);
    else {
      ll w;
      cin >> w;
      int z = lca(u, v), f = fa[z];
      vector<pair<int, int>> vc;
      qry(u, 1, vc), qry(v, 1, vc);
      qry(z, -1, vc), qry(f, -1, vc);
      int L = 0, R = A;
      i128 ans = ((i128)1) << 100, suf = sum;
      for (auto [r, d] : vc) suf -= tr[r].s2 * d;
      ll pcst = 0;
      int pcnt = 0;
      while (L < R) {
        int mid = (L + R) >> 1;
        i128 bs = suf;
        ll cst = pcst;
        int cnt = pcnt;
        for (auto [r, d] : vc)
          bs += d * tr[tr[r].l].s2, cst += d * tr[tr[r].r].s,
              cnt += d * tr[tr[r].r].c;
        ll d = cst - (mid + 1ll) * cnt;
        if (d <= w) {
          bs += i128(cnt) * (mid + 1) * (mid + 1);
          bs -= min<ll>(cnt, w - d) * i128(mid << 1 | 1);
          ans = min(ans, bs);
          R = mid, pcst = cst, pcnt = cnt;
          for (auto& [r, d] : vc) r = tr[r].l;
        } else {
          suf = bs, L = mid + 1;
          for (auto& [r, d] : vc) r = tr[r].r;
        }
      }
      cout << ans << '\n';
    }
  return cout << flush, 0;
}

詳細信息

Subtask #1:

score: 0
Dangerous Syscalls

Test #1:

score: 0
Dangerous Syscalls

input:

866 841
1 864
4 153
9 559
10 410
11 336
12 417
14 666
18 241
21 184
22 849
23 40
25 783
26 189
28 329
29 216
31 864
34 581
40 131
42 625
45 744
47 723
50 633
51 447
52 454
53 88
55 619
60 259
62 680
67 126
72 371
73 742
80 196
81 536
82 647
85 254
87 172
88 489
93 708
94 227
95 340
96 7
7 91
97 594
...

output:


result:


Subtask #2:

score: 0
Skipped

Dependency #1:

0%

Subtask #3:

score: 0
Dangerous Syscalls

Test #6:

score: 0
Dangerous Syscalls

input:

87080 98363
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 11
11 12
12 13
13 14
14 15
15 16
16 17
17 18
18 19
19 20
20 21
21 22
22 23
23 24
24 25
25 26
26 27
27 28
28 29
29 30
30 31
31 32
32 33
33 34
34 35
35 36
36 37
37 38
38 39
39 40
40 41
41 42
42 43
43 44
44 45
45 46
46 47
47 48
48 49
49 50
50 51
51 52...

output:


result:


Subtask #4:

score: 0
Skipped

Dependency #1:

0%