QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#105121#6322. ForestryHgCl2WA 768ms36228kbC++145.7kb2023-05-13 11:50:322023-05-13 11:50:35

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-05-13 11:50:35]
  • 评测
  • 测评结果:WA
  • 用时:768ms
  • 内存:36228kb
  • [2023-05-13 11:50:32]
  • 提交

answer

#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>

namespace {
using std::cin;
using std::cout;
using std::int64_t;
using std::size_t;

namespace base {
template <typename T, size_t... sizes>
struct NestedArray {};

template <typename T, size_t size, size_t... sizes>
struct NestedArray<T, size, sizes...> {
  using Type = std::array<typename NestedArray<T, sizes...>::Type, size>;
};

template <typename T>
struct NestedArray<T> {
  using Type = T;
};

template <typename T, size_t... sizes>
using Array = typename NestedArray<T, sizes...>::Type;

void OptimizeIO() {
  std::ios::sync_with_stdio(false);
  cin.tie(nullptr), cout.tie(nullptr);
}

void OptimizeIO(const std::string &input_file, const std::string &output_file) {
  static std::ifstream input_stream(input_file);
  static std::ofstream output_stream(output_file);
  cin.rdbuf(input_stream.rdbuf());
  cout.rdbuf(output_stream.rdbuf());
  cin.tie(nullptr), cout.tie(nullptr);
}
}  // namespace base

using base::Array;

const int kMod = 998244353, kInv2 = (kMod + 1) / 2;

namespace mod {
inline void Add(int &a, int b) {
  a += b;
  if (a >= kMod) a -= kMod;
}

inline int Sum(int a, int b) {
  a += b;
  if (a >= kMod) a -= kMod;
  return a;
}

inline void Sub(int &a, int b) {
  a -= b;
  if (a < 0) a += kMod;
}

inline int Diff(int a, int b) {
  a -= b;
  if (a < 0) a += kMod;
  return a;
}

inline void Mul(int &a, int b) { a = static_cast<int64_t>(a) * b % kMod; }

inline int Prod(int a, int b) { return static_cast<int64_t>(a) * b % kMod; }

int Pow(int a, int b) {
  int ans = 1, prod = a;

  while (b) {
    if (b & 1) Mul(ans, prod);
    Mul(prod, prod), b >>= 1;
  }

  return ans;
}

inline int Inv(int a) { return Pow(a, kMod - 2); }
}  // namespace mod

const int kMaxN = 3.0e5 + 5;
int n;
Array<int, kMaxN> f, sum_f, fa;
Array<int, kMaxN, 2> ch;
Array<bool, kMaxN> vis;
Array<std::vector<int>, kMaxN> edge;

struct Node {
  int val, id;
};

inline bool operator<(const Node &a, const Node &b) { return a.val < b.val; }

Array<Node, kMaxN> a;

struct Matrix {
  int a11, a13, a21, a23;
};

inline int Helper(int a, int b, int c) {
  return (static_cast<int64_t>(a) * b + c) % kMod;
}

inline Matrix operator*(const Matrix &a, const Matrix &b) {
  return {mod::Prod(a.a11, b.a11), Helper(a.a11, b.a13, a.a13),
          Helper(a.a21, b.a11, b.a21), Helper(a.a21, b.a13, b.a23 + a.a23)};
}

Array<Matrix, kMaxN> val, sum;

struct Info {
  int g, h;
};

inline Info operator+(const Info &a, Info b) {
  b.g = mod::Prod(b.g + 1, kInv2);
  return {mod::Prod(a.g, b.g), mod::Sum(a.h, b.h)};
}

inline Info operator-(const Info &a, Info b) {
  b.g = mod::Prod(b.g + 1, kInv2);
  if (a.g == 0 || b.g == 1) return {a.g, mod::Diff(a.h, b.h)};
  return {mod::Prod(a.g, mod::Inv(b.g)), mod::Diff(a.h, b.h)};
}

Matrix GenMatrix(const Info &info, bool f) {
  if (f) return {0, 0, 0, info.h};
  int half = mod::Prod(info.g, kInv2);
  return {half, half, half, mod::Sum(half, info.h)};
}

Info Retrodict(const Matrix &a, bool f) {
  if (f) return {0, a.a23};
  return {mod::Sum(a.a11, a.a11), mod::Diff(a.a23, a.a11)};
}

void Dfs(int u, int fa) {
  f[u] = 1;

  for (int v : edge[u]) {
    if (v == fa) continue;
    Dfs(v, u);
    mod::Mul(f[u], mod::Prod(f[v] + 1, kInv2));
    mod::Add(sum_f[u], sum_f[v]);
  }

  ::fa[u] = fa;
  sum[u] = val[u] = GenMatrix({f[u], sum_f[u]}, false);
  mod::Add(sum_f[u], f[u]);
}

inline bool IsRoot(int p) { return p != ch[fa[p]][0] && p != ch[fa[p]][1]; }

inline int Get(int p) { return p == ch[fa[p]][1]; }

inline void PushUp(int p) {
  int x = ch[p][0], y = ch[p][1];

  if (!x && !y) {
    sum[p] = val[p];
  } else if (!x) {
    sum[p] = val[p] * val[y];
  } else if (!y) {
    sum[p] = sum[x] * val[p];
  } else {
    sum[p] = sum[x] * val[p] * sum[y];
  }
}

void Rotate(int p) {
  int q = fa[p], k = Get(p);
  if (!IsRoot(q)) ch[fa[q]][Get(q)] = p;
  fa[p] = fa[q];
  ch[q][k] = ch[p][k ^ 1], fa[ch[p][k ^ 1]] = q;
  ch[p][k ^ 1] = q, fa[q] = p;
  PushUp(q), PushUp(p);
}

void Splay(int p) {
  while (!IsRoot(p)) {
    int q = fa[p];
    if (!IsRoot(q)) Get(p) == Get(q) ? Rotate(q) : Rotate(p);
    Rotate(p);
  }
}

inline Info Query(const Matrix &a) {
  return {mod::Sum(a.a11, a.a13), mod::Sum(a.a21, a.a23)};
}

void Access(int p) {
  int q = 0;

  while (p) {
    Splay(p);
    Info info = Retrodict(val[p], vis[p]);
    if (ch[p][1]) info = info + Query(sum[ch[p][1]]);
    if (q) info = info - Query(sum[q]);
    val[p] = GenMatrix(info, vis[p]);
    ch[p][1] = q, PushUp(p);
    q = p, p = fa[p];
  }
}

void Modify(int p) {
  Access(p), Splay(p);
  vis[p] = true;
  Info info = Retrodict(val[p], false);
  val[p] = GenMatrix(info, true);
  PushUp(p);
}

int Main() {
  base::OptimizeIO();
  cin >> n;

  for (int i = 1; i <= n; i++) {
    cin >> a[i].val;
    a[i].val %= kMod, a[i].id = i;
  }

  std::sort(a.begin() + 1, a.begin() + n + 1);

  for (int i = 1; i < n; i++) {
    int u, v;
    cin >> u >> v;
    edge[u].emplace_back(v), edge[v].emplace_back(u);
  }

  Dfs(1, 0);
  int ans = 0, p = 1;
  mod::Add(ans, mod::Prod(a[1].val, f[1] + sum_f[1]));

  while (p < n) {
    int i = p;
    while (i < n && a[i].val == a[p].val) Modify(a[i++].id);
    Access(1);
    Info res = Query(val[1]);
    mod::Add(ans, mod::Prod(a[i].val - a[p].val, res.g + res.h));
    p = i;
  }

  mod::Mul(ans, mod::Pow(2, n - 2));
  cout << ans << "\n";
  return 0;
}
}  // namespace

int main() { return Main(); }

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 2ms
memory: 11548kb

input:

4
1 2 3 4
1 2
2 4
3 2

output:

44

result:

ok 1 number(s): "44"

Test #2:

score: 0
Accepted
time: 1ms
memory: 11556kb

input:

5
3 5 6 5 1
4 1
2 3
3 5
1 3

output:

154

result:

ok 1 number(s): "154"

Test #3:

score: -100
Wrong Answer
time: 768ms
memory: 36228kb

input:

278989
864394090 384799247 186936242 598547507 962916136 540758021 158527118 688236322 682301622 948660645 881768181 481432818 557201870 794956026 205262301 920739629 141926922 990361777 818811172 150579096 1032726 328924563 638044961 21740781 484574329 737977343 113738003 345289940 363021157 582495...

output:

647634048

result:

wrong answer 1st numbers differ - expected: '434293031', found: '647634048'