QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#404481#8133. When Anton Saw This Task He Reacted With 😩RedGrey1993WA 2171ms255488kbC++1711.4kb2024-05-04 00:18:162024-05-04 00:18:16

Judging History

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

  • [2024-05-04 00:18:16]
  • 评测
  • 测评结果:WA
  • 用时:2171ms
  • 内存:255488kb
  • [2024-05-04 00:18:16]
  • 提交

answer

// #include <bits/stdc++.h>
#include "bits/stdc++.h"
 
using namespace std;
 
template <typename T1, typename T2> istream &operator>>(istream &is, pair<T1, T2> &pa) { is >> pa.first >> pa.second; return is; }
template <typename T> istream &operator>>(istream &is, vector<T> &vec) { for (auto &v : vec) is >> v; return is; }
template <typename T1, typename T2> ostream &operator<<(ostream &os, const pair<T1, T2> &pa) { os << "(" << pa.first << "," << pa.second << ")"; return os; }
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) { os << "["; for (auto v : vec) os << v << ","; os << "]"; return os; }
template <typename T> ostream &operator<<(ostream &os, const deque<T> &vec) { os << "deq["; for (auto v : vec) os << v << ","; os << "]"; return os; }
template <typename T> ostream &operator<<(ostream &os, const set<T> &vec) { os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template <typename T> ostream &operator<<(ostream &os, const multiset<T> &vec) { os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template <typename T> ostream &operator<<(ostream &os, const unordered_set<T> &vec) { os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template <typename T> ostream &operator<<(ostream &os, const unordered_multiset<T> &vec) { os << "{"; for (auto v : vec) os << v << ","; os << "}"; return os; }
template <typename TK, typename TV> ostream &operator<<(ostream &os, const unordered_map<TK, TV> &mp) { os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }
template <typename TK, typename TV> ostream &operator<<(ostream &os, const map<TK, TV> &mp) { os << "{"; for (auto v : mp) os << v.first << "=>" << v.second << ","; os << "}"; return os; }
template <typename T> void resize_array(vector<T> &vec, int len) { vec.resize(len); }
template <typename T, typename... Args> void resize_array(vector<T> &vec, int len, Args... args) { vec.resize(len); for (auto &v : vec) resize_array(v, args...); }
template <typename T1, typename T2> pair<T1, T2> operator+(const pair<T1, T2> &l, const pair<T1, T2> &r) { return make_pair(l.first + r.first, l.second + r.second); }
template <typename T1, typename T2> pair<T1, T2> operator-(const pair<T1, T2> &l, const pair<T1, T2> &r) { return make_pair(l.first - r.first, l.second - r.second); }
long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }
mt19937 mrand(random_device{}());
int rnd(int x) { return mrand() % x; }
 
#define rep(i, a, n) for (int i = a; i < (n); i++)
#define per(i, a, n) for (int i = (n)-1; i >= a; i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define fi first
#define se second
#define sz(x) ((int)(x).size())
typedef vector<int> vi;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef double db;
#if DEBUG
#define dbg(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl;
#else
#define dbg(x)
#endif


template <unsigned int MOD>
class ModInt {
public:
    ModInt(unsigned long long _v = 0) { set_v((_v % MOD + MOD)); }
    explicit operator bool() const { return val != 0; }
    ModInt operator-() const { return ModInt() - *this; }
    ModInt operator+(const ModInt &r) const { return ModInt().set_v(val + r.val); }
    ModInt operator-(const ModInt &r) const { return ModInt().set_v(val + MOD - r.val); }
    ModInt operator*(const ModInt &r) const { return ModInt().set_v((unsigned int)((unsigned long long)(val)*r.val % MOD)); }
    ModInt operator/(const ModInt &r) const { return *this * r.inv(); }
    ModInt &operator+=(const ModInt &r) { return *this = *this + r; }
    ModInt &operator-=(const ModInt &r) { return *this = *this - r; }
    ModInt &operator*=(const ModInt &r) { return *this = *this * r; }
    ModInt &operator/=(const ModInt &r) { return *this = *this / r; }
    // ModInt &operator=(unsigned long long _v) { set_v((_v % MOD + MOD)); return *this; }
    unsigned int operator=(unsigned long long _v) { set_v((_v % MOD + MOD)); return val; }
    bool operator==(const ModInt &r) const { return val == r.val; }
    bool operator!=(const ModInt &r) const { return val != r.val; }
    ModInt pow(long long n) const {
        ModInt x = *this, r = 1;
        while (n) {
            if (n & 1)
                r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    ModInt inv() const { return pow(MOD - 2); }
    friend ostream &operator<<(ostream &os, const ModInt &r) { return os << r.val; }
    friend istream &operator>>(istream &is, ModInt &r) { return is >> r.val; }
private:
    unsigned int val;
    ModInt &set_v(unsigned int _v) {
        val = (_v < MOD) ? _v : _v - MOD;
        return *this;
    }
};
using Mint = ModInt<998244353>;

template <typename T>
class StaticTopTree {
 public:
  enum Type { Vertex, Compress, Rake, AddEdge, AddVertex };
  StaticTopTree(vector<vector<int>> &g, int root = 0) : g_(g), root_(root) {
    int n = g_.size();
    parent_.resize(4 * n, -1);
    left_.resize(4 * n, -1);
    right_.resize(4 * n, -1);
    vertex_type_.resize(4 * n, Type::Vertex);
    paths_.resize(4 * n);
    points_.resize(4 * n);
    cur_idx_ = n;
    build();
  }

 private:
  // do HLD(Heavy Light Decomposition), move heavy edge to g_[c][0];
  int dfs(int c) {
    if (g_[c].size() > 0) {
      int t0 = dfs(g_[c][0]);
      int t1 = dfs(g_[c][1]);
      if (t0 > t1) sign_ = 1 - sign_;
      else swap(g_[c][0], g_[c][1]);
      return t0 + t1 + 1;
    }
    return 1;
  }
  int add(int k, int l, int r, Type t) {
    if (k == -1) k = cur_idx_++;
    parent_[k] = -1, left_[k] = l, right_[k] = r, vertex_type_[k] = t;
    if (l != -1) parent_[l] = k;
    if (r != -1) parent_[r] = k;
    return k;
  }
  pair<int, int> merge(const vector<pair<int, int>> &a, Type t) {
    if (a.size() == 1) return a[0];
    int u = 0;
    for (auto &[_, s] : a) u += s;
    vector<pair<int, int>> b, c;
    // make sure b/c at least has 1 item
    for (auto& [i, s] : a) (u > s ? b : c).emplace_back(i, s), u -= s * 2;
    // if use (u > 0 ? b : c), c may be 0 size, will be RE
    // for (auto &[i, s] : a) (u > 0 ? b : c).emplace_back(i, s), u -= s * 2;
    auto [i, si] = merge(b, t);
    auto [j, sj] = merge(c, t);
    return {add(-1, i, j, t), si + sj};
  }
  pair<int, int> compress(int i) {
    vector<pair<int, int>> chs{add_vertex(i)};
    while (!g_[i].empty()) chs.push_back(add_vertex(i = g_[i][0]));
    return merge(chs, Type::Compress);
  }
  pair<int, int> rake(int i) {
    vector<pair<int, int>> chs;
    for (int j = 1; j < (int)g_[i].size(); j++)
      chs.push_back(add_edge(g_[i][j]));
    return chs.empty() ? make_pair(-1, 0) : merge(chs, Type::Rake);
  }
  pair<int, int> add_edge(int i) {
    auto [j, sj] = compress(i);
    return {add(-1, j, -1, Type::AddEdge), sj};
  }
  pair<int, int> add_vertex(int i) {
    auto [j, sj] = rake(i);
    return {add(i, j, -1, j == -1 ? Type::Vertex : Type::AddVertex), sj + 1};
  }
  void build() {
    dfs(root_);
    auto [i, n] = compress(root_);
    stt_root_ = i;
  }
  // private:
 public:
  // adjacent list of initial tree, chridren are stored in g_[parent],
  // parent can not be stored in g_[child] in this implement!!!
  // g_ must be a rooted tree
  vector<vector<int>> &g_;
  int root_;      // an index of the root in g
  int stt_root_;  // an index of the root in static top tree
  vector<int> parent_, left_, right_;  // parent, left child, right child
  vector<Type> vertex_type_;           // type of vertices
  int cur_idx_;                        // a variable for the index increment

  vector<vector<T>> values;
  int sign_ = 0;

 private:
  struct Mat {
    Mat() {
      resize_array(m, 3, 3);
      m[0][0]=m[1][1]=m[2][2]=1;
    }
    Mat operator*(const Mat& b) const {
      Mat ans;
      rep(i,0,3) rep(j,0,3) {
        ans.m[i][j] = 0;
        rep(k,0,3) {
          ans.m[i][j] += m[i][k] * b.m[k][j];
        }
      }
      return ans;
    }
    vector<T> operator*(const vector<T>& b) const {
      vector<T> ans(3);
      rep(i,0,3) {
        ans[i] = 0;
        rep(k,0,3) {
          ans[i] += m[i][k] * b[k];
        }
      }
      return ans;
    }
    vector<vector<T>> m;
  };
  struct Point {
    Point() { v.resize(3); }
    Point(const vector<T>& b) { v = b; }
    vector<T> v;
  };
  struct Path {
    Mat m;
    vector<T> v;
  };
  vector<Point> points_;
  vector<Path> paths_;
  Path vertex(int i) { Path p; p.v = values[i]; return p; }
  Path compress(Path p, Path c) { Path ans; ans.m = p.m * c.m; ans.v = c.v; return ans; }
  Path add_vertex(Point p, int i) { Path ans; ans.m.m = vector<vector<T>>({{0,-p.v[2],p.v[1]},{p.v[2],0,-p.v[0]},{-p.v[1],p.v[0],0}}); return ans; }
  Point add_edge(Path p) { return p.m * p.v; }
  Point rake(Point l, Point r) { return Point(); }

  void update_node(int k) {
    if (vertex_type_[k] == Vertex) paths_[k] = vertex(k);
    else if (vertex_type_[k] == Compress) paths_[k] = compress(paths_[left_[k]], paths_[right_[k]]);
    if (vertex_type_[k] == AddVertex) paths_[k] = add_vertex(points_[left_[k]], k);
    if (vertex_type_[k] == AddEdge) points_[k] = add_edge(paths_[left_[k]]);
    if (vertex_type_[k] == Rake) points_[k] = rake(points_[left_[k]], points_[right_[k]]);
  }

  void init(int k) {
    if (left_[k] != -1) init(left_[k]);
    if (right_[k] != -1) init(right_[k]);
    update_node(k);
  }

 public:
  void update_tree(int k, vector<T> v) {
    values[k] = v;
    while (k != -1) {
      update_node(k);
      k = parent_[k];
    }
  }

  void init() {
    init(stt_root_);
  }

  vector<T> get_answer() {
    return paths_[stt_root_].m * paths_[stt_root_].v;
  }
};

class Solution {
public:
    void Solve() {
        int n,q;
        while(cin>>n>>q) {
            vector<vi> edges(n);
            char op;
            int x,y,z;
            vector<vector<Mint>> values(n);
            rep(i,0,n) {
              cin>>op;
              if (op=='x') {
                cin>>x>>y;
                edges[i].emplace_back(x-1);
                edges[i].emplace_back(y-1);
              } else {
                cin>>x>>y>>z;
                values[i]={x,y,z};
              }
            }

            // dbg(edges);
            StaticTopTree<Mint> stt(edges);
            stt.values = std::move(values);
            stt.init();

            // cout << stt.get_answer() << "\n";

            int k;
            rep(i,0,q) {
                cin>>k>>x>>y>>z;
                stt.update_tree(k-1, {x,y,z});
                // cout << stt.get_answer() << "\n";
                auto ans = stt.get_answer();
                int s = 1; if (stt.sign_ == 1) s = -1;
                rep(i,0,3) {
                  if (i)cout<<" ";
                  cout << ans[i]*s;
                }
                cout<<"\n";
            }
        }
        cout.flush();
    }
private:
};
 
// #define USACO 1
void set_io(const string &name = "") {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
#if FILE_IO || USACO
    if (!name.empty()) {
        freopen((name + ".in").c_str(), "r", stdin);
        freopen((name + ".out").c_str(), "w", stdout);
    }
#endif
}

int main() {
#if USACO
    set_io("time");
#else
    set_io("tmp");
#endif
    Solution().Solve();

    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 3464kb

input:

5 3
x 2 3
v 1 0 1
x 4 5
v 0 2 1
v 1 1 1
4 1 2 3
5 0 1 1
4 0 2 2

output:

998244351 0 2
1 998244351 998244352
0 0 0

result:

ok 9 numbers

Test #2:

score: 0
Accepted
time: 2171ms
memory: 255488kb

input:

199999 100000
x 137025 65661
v 572518668 158967010 74946561
x 129836 192657
x 141948 187810
v 574918069 328924434 141474729
x 143312 111002
x 52772 148497
v 922857701 690080961 651915759
v 656198340 28002884 129579416
v 639893144 265359784 646791226
v 796871409 411409966 598676495
v 882562617 224394...

output:

393120558 773766615 387297348
759959566 981774500 128012497
294611811 980011608 533642029
404379574 745296852 53493560
404565501 828869760 78021156
592494858 647751304 881427733
190018467 515243135 518180555
628180500 509984554 257430135
13737245 352087791 917410487
932051309 366591227 479931477
199...

result:

ok 300000 numbers

Test #3:

score: -100
Wrong Answer
time: 2079ms
memory: 254916kb

input:

199999 100000
x 154525 80092
v 450407262 725458410 590777520
x 24720 135901
v 719242117 114943104 186796011
v 382530926 89156744 943939337
x 183376 26042
x 109984 157873
x 151637 150600
x 4115 27454
x 163135 92648
x 16764 33212
v 849210403 945083972 689295397
v 471196117 68587428 225597765
x 24643 5...

output:

769248474 892842499 367009271
318933736 975613687 54298279
10736748 144818389 674379257
277911987 384283617 356565359
637380912 270945930 950149309
445156411 767254942 747349542
74761950 135434472 391284893
602283306 727101594 541798701
259041999 206334592 66442191
509003192 479929452 142509733
8174...

result:

wrong answer 1st numbers differ by non-multiple of MOD, - expected: '677067461', found: '769248474'