QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#260397#7839. 虹hos_lyric#50 1698ms27416kbC++1421.3kb2023-11-22 07:24:472024-07-04 03:08:12

Judging History

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

  • [2024-07-04 03:08:12]
  • 评测
  • 测评结果:50
  • 用时:1698ms
  • 内存:27416kb
  • [2023-11-22 07:24:47]
  • 提交

answer

#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

using Int = long long;

template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")

////////////////////////////////////////////////////////////////////////////////
template <unsigned M_> struct ModInt {
  static constexpr unsigned M = M_;
  unsigned x;
  constexpr ModInt() : x(0U) {}
  constexpr ModInt(unsigned x_) : x(x_ % M) {}
  constexpr ModInt(unsigned long long x_) : x(x_ % M) {}
  constexpr ModInt(int x_) : x(((x_ %= static_cast<int>(M)) < 0) ? (x_ + static_cast<int>(M)) : x_) {}
  constexpr ModInt(long long x_) : x(((x_ %= static_cast<long long>(M)) < 0) ? (x_ + static_cast<long long>(M)) : x_) {}
  ModInt &operator+=(const ModInt &a) { x = ((x += a.x) >= M) ? (x - M) : x; return *this; }
  ModInt &operator-=(const ModInt &a) { x = ((x -= a.x) >= M) ? (x + M) : x; return *this; }
  ModInt &operator*=(const ModInt &a) { x = (static_cast<unsigned long long>(x) * a.x) % M; return *this; }
  ModInt &operator/=(const ModInt &a) { return (*this *= a.inv()); }
  ModInt pow(long long e) const {
    if (e < 0) return inv().pow(-e);
    ModInt a = *this, b = 1U; for (; e; e >>= 1) { if (e & 1) b *= a; a *= a; } return b;
  }
  ModInt inv() const {
    unsigned a = M, b = x; int y = 0, z = 1;
    for (; b; ) { const unsigned q = a / b; const unsigned c = a - q * b; a = b; b = c; const int w = y - static_cast<int>(q) * z; y = z; z = w; }
    assert(a == 1U); return ModInt(y);
  }
  ModInt operator+() const { return *this; }
  ModInt operator-() const { ModInt a; a.x = x ? (M - x) : 0U; return a; }
  ModInt operator+(const ModInt &a) const { return (ModInt(*this) += a); }
  ModInt operator-(const ModInt &a) const { return (ModInt(*this) -= a); }
  ModInt operator*(const ModInt &a) const { return (ModInt(*this) *= a); }
  ModInt operator/(const ModInt &a) const { return (ModInt(*this) /= a); }
  template <class T> friend ModInt operator+(T a, const ModInt &b) { return (ModInt(a) += b); }
  template <class T> friend ModInt operator-(T a, const ModInt &b) { return (ModInt(a) -= b); }
  template <class T> friend ModInt operator*(T a, const ModInt &b) { return (ModInt(a) *= b); }
  template <class T> friend ModInt operator/(T a, const ModInt &b) { return (ModInt(a) /= b); }
  explicit operator bool() const { return x; }
  bool operator==(const ModInt &a) const { return (x == a.x); }
  bool operator!=(const ModInt &a) const { return (x != a.x); }
  friend std::ostream &operator<<(std::ostream &os, const ModInt &a) { return os << a.x; }
};
////////////////////////////////////////////////////////////////////////////////

constexpr unsigned MO = 20242024;
using Mint = ModInt<MO>;

struct Hld {
  int n, rt;
  // needs to be tree
  // vertex lists
  // modified in build(rt) (parent removed, heavy child first)
  vector<vector<int>> graph;
  vector<int> sz, par, dep;
  int zeit;
  vector<int> dis, fin, sid;
  // head vertex (minimum depth) in heavy path
  vector<int> head;

  Hld() : n(0), rt(-1), zeit(0) {}
  explicit Hld(int n_) : n(n_), rt(-1), graph(n), zeit(0) {}
  void ae(int u, int v) {
    assert(0 <= u); assert(u < n);
    assert(0 <= v); assert(v < n);
    graph[u].push_back(v);
    graph[v].push_back(u);
  }

  void dfsSz(int u) {
    sz[u] = 1;
    for (const int v : graph[u]) {
      auto it = std::find(graph[v].begin(), graph[v].end(), u);
      if (it != graph[v].end()) graph[v].erase(it);
      par[v] = u;
      dep[v] = dep[u] + 1;
      dfsSz(v);
      sz[u] += sz[v];
    }
  }
  void dfsHld(int u) {
    dis[u] = zeit++;
    const int deg = graph[u].size();
    if (deg > 0) {
      int vm = graph[u][0];
      int jm = 0;
      for (int j = 1; j < deg; ++j) {
        const int v = graph[u][j];
        if (sz[vm] < sz[v]) {
          vm = v;
          jm = j;
        }
      }
      swap(graph[u][0], graph[u][jm]);
      head[vm] = head[u];
      dfsHld(vm);
      for (int j = 1; j < deg; ++j) {
        const int v = graph[u][j];
        head[v] = v;
        dfsHld(v);
      }
    }
    fin[u] = zeit;
  }
  void build(int rt_) {
    assert(0 <= rt_); assert(rt_ < n);
    rt = rt_;
    sz.assign(n, 0);
    par.assign(n, -1);
    dep.assign(n, -1);
    dep[rt] = 0;
    dfsSz(rt);
    zeit = 0;
    dis.assign(n, -1);
    fin.assign(n, -1);
    head.assign(n, -1);
    head[rt] = rt;
    dfsHld(rt);
    assert(zeit == n);
    sid.assign(n, -1);
    for (int u = 0; u < n; ++u) sid[dis[u]] = u;
  }

  friend ostream &operator<<(ostream &os, const Hld &hld) {
    const int maxDep = *max_element(hld.dep.begin(), hld.dep.end());
    vector<string> ss(2 * maxDep + 1);
    int pos = 0, maxPos = 0;
    for (int j = 0; j < hld.n; ++j) {
      const int u = hld.sid[j];
      const int d = hld.dep[u];
      if (hld.head[u] == u) {
        if (j != 0) {
          pos = maxPos + 1;
          ss[2 * d - 1].resize(pos, '-');
          ss[2 * d - 1] += '+';
        }
      } else {
        ss[2 * d - 1].resize(pos, ' ');
        ss[2 * d - 1] += '|';
      }
      ss[2 * d].resize(pos, ' ');
      ss[2 * d] += std::to_string(u);
      if (maxPos < static_cast<int>(ss[2 * d].size())) {
        maxPos = ss[2 * d].size();
      }
    }
    for (int d = 0; d <= 2 * maxDep; ++d) os << ss[d] << '\n';
    return os;
  }

  bool contains(int u, int v) const {
    return (dis[u] <= dis[v] && dis[v] < fin[u]);
  }
  int lca(int u, int v) const {
    assert(0 <= u); assert(u < n);
    assert(0 <= v); assert(v < n);
    for (; head[u] != head[v]; ) (dis[u] > dis[v]) ? (u = par[head[u]]) : (v = par[head[v]]);
    return (dis[u] > dis[v]) ? v : u;
  }
  int jumpUp(int u, int d) const {
    assert(0 <= u); assert(u < n);
    assert(d >= 0);
    if (dep[u] < d) return -1;
    const int tar = dep[u] - d;
    for (u = head[u]; ; u = head[par[u]]) {
      if (dep[u] <= tar) return sid[dis[u] + (tar - dep[u])];
    }
  }
  int jump(int u, int v, int d) const {
    assert(0 <= u); assert(u < n);
    assert(0 <= v); assert(v < n);
    assert(d >= 0);
    const int l = lca(u, v);
    const int du = dep[u] - dep[l], dv = dep[v] - dep[l];
    if (d <= du) {
      return jumpUp(u, d);
    } else if (d <= du + dv) {
      return jumpUp(v, du + dv - d);
    } else {
      return -1;
    }
  }
  // [u, v) or [u, v]
  template <class F> void doPathUp(int u, int v, bool inclusive, F f) const {
    assert(contains(v, u));
    for (; head[u] != head[v]; u = par[head[u]]) f(dis[head[u]], dis[u] + 1);
    if (inclusive) {
      f(dis[v], dis[u] + 1);
    } else {
      if (v != u) f(dis[v] + 1, dis[u] + 1);
    }
  }
  // not path order, include lca(u, v) or not
  template <class F> void doPath(int u, int v, bool inclusive, F f) const {
    const int l = lca(u, v);
    doPathUp(u, l, false, f);
    doPathUp(v, l, inclusive, f);
  }

  // (vs, ps): compressed tree
  // vs: DFS order (sorted by dis)
  // vs[ps[x]]: the parent of vs[x]
  // ids[vs[x]] = x, not set for non-tree vertex
  vector<int> ids;
  pair<vector<int>, vector<int>> compress(vector<int> us) {
    // O(n) first time
    ids.resize(n, -1);
    std::sort(us.begin(), us.end(), [&](int u, int v) -> bool {
      return (dis[u] < dis[v]);
    });
    us.erase(std::unique(us.begin(), us.end()), us.end());
    int usLen = us.size();
    assert(usLen >= 1);
    for (int x = 1; x < usLen; ++x) us.push_back(lca(us[x - 1], us[x]));
    std::sort(us.begin(), us.end(), [&](int u, int v) -> bool {
      return (dis[u] < dis[v]);
    });
    us.erase(std::unique(us.begin(), us.end()), us.end());
    usLen = us.size();
    for (int x = 0; x < usLen; ++x) ids[us[x]] = x;
    vector<int> ps(usLen, -1);
    for (int x = 1; x < usLen; ++x) ps[x] = ids[lca(us[x - 1], us[x])];
    return make_pair(us, ps);
  }
};

////////////////////////////////////////////////////////////////////////////////


// [0, n), 0 <= n <= 2^(6D)
template <int D> struct Set {
  int n;
  vector<unsigned long long> a[D];
  explicit Set(int n_ = 0) : n(n_) {
    static_assert(1 <= D && D <= 6, "Set: 1 <= D <= 6 must hold");
    assert(0 <= n); assert(n <= 1LL << (6 * D));
    int m = n ? n : 1;
    for (int d = 0; d < D; ++d) {
      m = (m + 63) >> 6;
      a[d].assign(m, 0);
    }
  }
  bool empty() const {
    return !a[D - 1][0];
  }
  bool contains(int x) const {
    return (a[0][x >> 6] >> (x & 63)) & 1;
  }
  void insert(int x) {
    for (int d = 0; d < D; ++d) {
      const int q = x >> 6, r = x & 63;
      a[d][q] |= 1ULL << r;
      x = q;
    }
  }
  void erase(int x) {
    for (int d = 0; d < D; ++d) {
      const int q = x >> 6, r = x & 63;
      if ((a[d][q] &= ~(1ULL << r))) break;
      x = q;
    }
  }
  // min s.t. >= x
  int next(int x) const {
    for (int d = 0; d < D; ++d) {
      const int q = x >> 6, r = x & 63;
      if (static_cast<unsigned>(q) >= a[d].size()) break;
      const unsigned long long upper = a[d][q] >> r;
      if (upper) {
        x += __builtin_ctzll(upper);
        for (int e = d - 1; e >= 0; --e) x = x << 6 | __builtin_ctzll(a[e][x]);
        return x;
      }
      x = q + 1;
    }
    return n;
  }
  // max s.t. <= x
  int prev(int x) const {
    for (int d = 0; d < D; ++d) {
      if (x < 0) break;
      const int q = x >> 6, r = x & 63;
      const unsigned long long lower = a[d][q] << (63 - r);
      if (lower) {
        x -= __builtin_clzll(lower);
        for (int e = d - 1; e >= 0; --e) x = x << 6 | (63 - __builtin_clzll(a[e][x]));
        return x;
      }
      x = q - 1;
    }
    return -1;
  }
};

////////////////////////////////////////////////////////////////////////////////


// T: monoid representing information of an interval.
//   T()  should return the identity.
//   T(S s)  should represent a single element of the array.
//   T::push(T &l, T &r)  should push the lazy update.
//   T::pull(const T &l, const T &r)  should pull two intervals.
template <class T> struct SegmentTreeRange {
  int logN, n;
  vector<T> ts;
  SegmentTreeRange() : logN(0), n(0) {}
  explicit SegmentTreeRange(int n_) {
    for (logN = 0, n = 1; n < n_; ++logN, n <<= 1) {}
    ts.resize(n << 1);
  }
  template <class S> explicit SegmentTreeRange(const vector<S> &ss) {
    const int n_ = ss.size();
    for (logN = 0, n = 1; n < n_; ++logN, n <<= 1) {}
    ts.resize(n << 1);
    for (int i = 0; i < n_; ++i) at(i) = T(ss[i]);
    build();
  }
  T &at(int i) {
    return ts[n + i];
  }
  void build() {
    for (int u = n; --u; ) pull(u);
  }

  inline void push(int u) {
    ts[u].push(ts[u << 1], ts[u << 1 | 1]);
  }
  inline void pull(int u) {
    ts[u].pull(ts[u << 1], ts[u << 1 | 1]);
  }

  // Applies T::f(args...) to [a, b).
  template <class F, class... Args>
  void ch(int a, int b, F f, Args &&... args) {
    assert(0 <= a); assert(a <= b); assert(b <= n);
    if (a == b) return;
    a += n; b += n;
    for (int h = logN; h; --h) {
      const int aa = a >> h, bb = b >> h;
      if (aa == bb) {
        if ((aa << h) != a || (bb << h) != b) push(aa);
      } else {
        if ((aa << h) != a) push(aa);
        if ((bb << h) != b) push(bb);
      }
    }
    for (int aa = a, bb = b; aa < bb; aa >>= 1, bb >>= 1) {
      if (aa & 1) (ts[aa++].*f)(args...);
      if (bb & 1) (ts[--bb].*f)(args...);
    }
    for (int h = 1; h <= logN; ++h) {
      const int aa = a >> h, bb = b >> h;
      if (aa == bb) {
        if ((aa << h) != a || (bb << h) != b) pull(aa);
      } else {
        if ((aa << h) != a) pull(aa);
        if ((bb << h) != b) pull(bb);
      }
    }
  }

  // Calculates the product for [a, b).
  T get(int a, int b) {
    assert(0 <= a); assert(a <= b); assert(b <= n);
    if (a == b) return T();
    a += n; b += n;
    for (int h = logN; h; --h) {
      const int aa = a >> h, bb = b >> h;
      if (aa == bb) {
        if ((aa << h) != a || (bb << h) != b) push(aa);
      } else {
        if ((aa << h) != a) push(aa);
        if ((bb << h) != b) push(bb);
      }
    }
    T prodL, prodR, t;
    for (int aa = a, bb = b; aa < bb; aa >>= 1, bb >>= 1) {
      if (aa & 1) { t.pull(prodL, ts[aa++]); prodL = t; }
      if (bb & 1) { t.pull(ts[--bb], prodR); prodR = t; }
    }
    t.pull(prodL, prodR);
    return t;
  }

  // Calculates T::f(args...) of a monoid type for [a, b).
  //   op(-, -)  should calculate the product.
  //   e()  should return the identity.
  template <class Op, class E, class F, class... Args>
#if __cplusplus >= 201402L
  auto
#else
  decltype((std::declval<T>().*F())())
#endif
  get(int a, int b, Op op, E e, F f, Args &&... args) {
    assert(0 <= a); assert(a <= b); assert(b <= n);
    if (a == b) return e();
    a += n; b += n;
    for (int h = logN; h; --h) {
      const int aa = a >> h, bb = b >> h;
      if (aa == bb) {
        if ((aa << h) != a || (bb << h) != b) push(aa);
      } else {
        if ((aa << h) != a) push(aa);
        if ((bb << h) != b) push(bb);
      }
    }
    auto prodL = e(), prodR = e();
    for (int aa = a, bb = b; aa < bb; aa >>= 1, bb >>= 1) {
      if (aa & 1) prodL = op(prodL, (ts[aa++].*f)(args...));
      if (bb & 1) prodR = op((ts[--bb].*f)(args...), prodR);
    }
    return op(prodL, prodR);
  }

  // Find min b s.t. T::f(args...) returns true,
  // when called for the partition of [a, b) from left to right.
  //   Returns n + 1 if there is no such b.
  template <class F, class... Args>
  int findRight(int a, F f, Args &&... args) {
    assert(0 <= a); assert(a <= n);
    if ((T().*f)(args...)) return a;
    if (a == n) return n + 1;
    a += n;
    for (int h = logN; h; --h) push(a >> h);
    for (; ; a >>= 1) if (a & 1) {
      if ((ts[a].*f)(args...)) {
        for (; a < n; ) {
          push(a);
          if (!(ts[a <<= 1].*f)(args...)) ++a;
        }
        return a - n + 1;
      }
      ++a;
      if (!(a & (a - 1))) return n + 1;
    }
  }

  // Find max a s.t. T::f(args...) returns true,
  // when called for the partition of [a, b) from right to left.
  //   Returns -1 if there is no such a.
  template <class F, class... Args>
  int findLeft(int b, F f, Args &&... args) {
    assert(0 <= b); assert(b <= n);
    if ((T().*f)(args...)) return b;
    if (b == 0) return -1;
    b += n;
    for (int h = logN; h; --h) push((b - 1) >> h);
    for (; ; b >>= 1) if ((b & 1) || b == 2) {
      if ((ts[b - 1].*f)(args...)) {
        for (; b <= n; ) {
          push(b - 1);
          if (!(ts[(b <<= 1) - 1].*f)(args...)) --b;
        }
        return b - n - 1;
      }
      --b;
      if (!(b & (b - 1))) return -1;
    }
  }
};

////////////////////////////////////////////////////////////////////////////////

constexpr Mint S = 19901991;

int N, Q;
vector<int> Z, ZZ;
vector<int> A, B;
vector<int> O, L, R, T;

Hld hld;


namespace brute {
vector<Mint> run() {
cerr<<"[brute::run]"<<endl;
  vector<Mint> anss;
  vector<int> ws(N, 0);
  for (int q = 0; q < Q; ++q) {
    if (O[q] == 1) {
      vector<int> dp(N, 0);
      for (int u = L[q]; u < R[q]; ++u) {
        dp[u] = 1;
      }
      for (int j = N; --j >= 0; ) {
        const int u = hld.sid[j];
        if (dp[u]) {
          ++ws[u];
        }
        if (dp[u] == R[q] - L[q]) {
          break;
        }
        dp[hld.par[u]] += dp[u];
      }
    } else {
// cerr<<"ws = "<<ws<<endl;
      Mint ans = 0;
      for (int u = L[q]; u < R[q]; ++u) {
        ans += S.pow((Int)Z[__gcd(u + 1, T[q])] * ws[u]);
      }
      anss.push_back(ans);
    }
  }
  return anss;
}
}  // brute


namespace subA {
struct Query {
  int l, r;
};

// (x, y) -> (x + a y + b, y + c)
struct Node {
  int a, b, c;
  Node() : a(0), b(0), c(0) {}
  void push(Node &l, Node &r) {
    if (a || b || c) {
      l.apply(a, b, c);
      r.apply(a, b, c);
      a = b = c = 0;
    }
  }
  void pull(const Node &, const Node &) {
    //
  }
  void apply(Int aa, Int bb, Int cc) {
    a += aa;
    b += aa * c + bb;
    c += cc;
  }
};

Set<3> on;
SegmentTreeRange<Node> seg;
vector<int> ws;
void init() {
  on = Set<3>(N);
  seg = SegmentTreeRange<Node>(N);
  ws.assign(N, 0);
}
int calc(int u, int l, int r) {
  int ret = 0;
  for (const int j : {l, r}) if (0 <= j && j < N) {
    const int res = hld.lca(u, hld.sid[j]);
    if (hld.dis[ret] < hld.dis[res]) {
      ret = res;
    }
  }
  return ret;
}
void add(int u) {
  const int j = hld.dis[u];
  const int l = on.prev(j);
  const int r = on.next(j);
  on.insert(j);
  const int v = calc(u, l, r);
// cerr<<COLOR("91")<<"[add] "<<u<<" "<<v<<COLOR()<<endl;
  hld.doPathUp(u, v, false, [&](int jL, int jR) -> void {
    seg.ch(jL, jR, &Node::apply, 0, 0, +1);
  });
}
void rem(int u) {
  const int j = hld.dis[u];
  on.erase(j);
  const int l = on.prev(j);
  const int r = on.next(j);
  const int v = calc(u, l, r);
// cerr<<COLOR("94")<<"[rem] "<<u<<" "<<v<<COLOR()<<endl;
  hld.doPathUp(u, v, false, [&](int jL, int jR) -> void {
    seg.ch(jL, jR, &Node::apply, 0, 0, -1);
  });
}
void go() {
  assert(!on.empty());
  const int l = on.next(0);
  const int r = on.prev(N - 1);
  const int v = hld.lca(hld.sid[l], hld.sid[r]);
// cerr<<COLOR("93")<<"[go] "<<v<<COLOR()<<endl;
  hld.doPathUp(v, 0, false, [&](int jL, int jR) -> void {
    seg.ch(jL, jR, &Node::apply, 0, 0, -1);
  });
  ++ws[v];
  seg.ch(0, N, &Node::apply, +1, 0, 0);
  hld.doPathUp(v, 0, false, [&](int jL, int jR) -> void {
    seg.ch(jL, jR, &Node::apply, 0, 0, +1);
  });
}

vector<Mint> run() {
cerr<<"[subA::run]"<<endl;
  vector<Query> qrs;
  for (int q = 0; q < Q; ++q) if (O[q] == 1) {
    qrs.emplace_back(Query{L[q], R[q]});
  }
  const int sz = max<int>(N / max<int>(sqrt(qrs.size()), 1), 1);
  sort(qrs.begin(), qrs.end(), [&](const Query &qra, const Query &qrb) -> bool {
    const int xa = qra.l / sz;
    const int xb = qrb.l / sz;
    return ((xa != xb) ? (xa < xb) : (xa & 1) ? (qra.r > qrb.r) : (qra.r < qrb.r));
  });
  init();
  int l = 0, r = 0;
  for (const auto &qr : qrs) {
    for (; l > qr.l; ) add(--l);
    for (; r < qr.r; ) add(r++);
    for (; l < qr.l; ) rem(l++);
    for (; r > qr.r; ) rem(--r);
    go();
  }
  for (int j = 1; j < seg.n; ++j) {
    seg.push(j);
  }
  for (int u = 0; u < N; ++u) {
    ws[u] += seg.at(hld.dis[u]).b;
  }
// cerr<<"ws = "<<ws<<endl;
  
  vector<vector<int>> dss(N + 1);
  vector<vector<int>> fss(N + 1);
  for (int d = 1; d <= N; ++d) {
    const int len = N / d;
    fss[d].assign(len + 1, 0);
    for (int e = 1; e <= len; ++e) {
      const int u = d * e;
      dss[u].push_back(d);
      fss[d][e] = fss[d][e - 1] + (ws[u - 1] & 1);
    }
  }
  vector<Mint> anss;
  for (int q = 0; q < Q; ++q) if (O[q] == 2) {
    int sum = 0;
    for (const int d : dss[T[q]]) {
      sum += ZZ[d] * (fss[d][R[q] / d] - fss[d][L[q] / d]);
    }
    Mint ans = R[q] - L[q];
    ans += Mint(sum) * Mint(S - 1);
    anss.push_back(ans);
  }
  return anss;
}
}  // subA


int main() {
  assert(S * S == 1);
  
  for (; ~scanf("%d%d", &N, &Q); ) {
    Z.assign(N + 1, 0);
    for (int x = 1; x <= N; ++x) {
      scanf("%d", &Z[x]);
      Z[x] &= 1;
    }
    A.resize(N - 1);
    B.resize(N - 1);
    for (int i = 0; i < N - 1; ++i) {
      scanf("%d%d", &A[i], &B[i]);
      --A[i];
      --B[i];
    }
    O.resize(Q);
    L.resize(Q);
    R.resize(Q);
    T.assign(Q, 0);
    for (int q = 0; q < Q; ++q) {
      scanf("%d%d%d", &O[q], &L[q], &R[q]);
      --L[q];
      if (O[q] == 2) {
        scanf("%d", &T[q]);
      }
    }
    
    hld = Hld(N);
    for (int i = 0; i < N - 1; ++i) {
      hld.ae(A[i], B[i]);
    }
    hld.build(0);
// cerr<<hld<<endl;
    
    // Z * moe
    ZZ = Z;
    for (int d = 1; d <= N; ++d) {
      for (int x = 2 * d; x <= N; x += d) {
        ZZ[x] -= ZZ[d];
      }
    }
// cerr<<"ZZ = "<<ZZ<<endl;
    
    bool speA = true;
    for (int q = 0; q < Q - 1; ++q) {
      speA = speA && (O[q] <= O[q + 1]);
    }
    
    vector<Mint> anss;
    if (speA) {
      anss = subA::run();
    } else {
      anss = brute::run();
    }
    for (const Mint ans : anss) {
      printf("%u\n", ans.x);
    }
#ifdef LOCAL
const auto brt=brute::run();
if(brt!=anss){
 cerr<<"brt  = "<<brt<<endl;
 cerr<<"anss = "<<anss<<endl;
}
assert(brt==anss);
#endif
  }
  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Subtask #1:

score: 10
Accepted

Test #1:

score: 10
Accepted
time: 11ms
memory: 4172kb

input:

998 1000
955556485 952505211 899166521 258704448 894183248 636280051 62949347 983956660 113872828 588367167 208142006 665025449 944228063 284736189 169202015 56096447 404419923 30158095 111191865 717455344 790159420 391379127 208279658 426780799 886604643 940903663 618716147 773652834 385881251 1593...

output:

16521790
13341944
16841705
2220375
880451
3621051
12662029
6300750
3240463
2400556
6501168
3580517
9221391
8381420
12982211
8001004
9361122
17262479
3600913
10401408
16202143
15022309
16341874
7861442
1560390
8340899
12421304
13961591
10421679
12101636
17361912
11781615
4780673
13641787
20102392
171...

result:

ok 490 lines

Test #2:

score: 0
Accepted
time: 12ms
memory: 4256kb

input:

1000 997
103470799 773962597 977631665 55926526 616833039 263471628 825848455 638144717 340710593 68036397 623497249 808915869 345157828 256095693 400262335 173843004 238983751 646376872 243739767 221162275 465477137 772061029 840064611 274062983 522264159 689460088 20129595 287189331 622217799 6948...

output:

13621441
17282360
11241382
15841876
17222347
1880319
12441746
10381083
18222171
7341024
10081427
2900456
2900406
13801602
17521768
19901997
8521022
13281468
2400503
17201967
19942477
14461494
19742168
14461471
12121799
2600806
18902095
1941004
19901993
10221200
8901579
9201080
19442423
720422
130019...

result:

ok 527 lines

Test #3:

score: 0
Accepted
time: 10ms
memory: 4236kb

input:

1000 1000
1697351 841785432 606301324 899151762 398181773 419939453 419455373 826820357 965555426 240847697 718049384 378823565 364137136 867089279 445499605 934770217 134914678 642584637 766848023 203338778 153291975 240768524 446186401 462123008 408740063 755064293 274502953 646610365 27815415 164...

output:

368
198
7021295
16001721
18602311
8021119
17201976
1380573
13141934
3580444
14641604
16681966
3240524
16182225
7541265
8520964
6341385
18922654
17861873
13781440
11581327
14342249
3600640
6821000
16841702
860350
16501686
3420674
18881910
6161028
17022054
3920543
4600572
6300810
3761005
11401360
8181...

result:

ok 502 lines

Subtask #2:

score: 20
Accepted

Test #4:

score: 20
Accepted
time: 1649ms
memory: 26632kb

input:

65531 65535
968854923 932574892 192297572 866236747 654755663 148562561 273214896 947434573 938626677 992982166 219888853 229840279 676071061 383387319 372883953 729287797 601010887 31942080 990584163 823724544 181337075 918252129 896876911 768539961 357780649 890577681 819641335 320266037 55445939 ...

output:

2662122
12263904
9988949
9098885
10661570
169420
12206075
11189204
12737561
19687277
3177635
12864425
16522132
8890301
19817862
19631288
14433359
4841805
15087340
13737927

result:

ok 20 lines

Test #5:

score: 0
Accepted
time: 1689ms
memory: 27084kb

input:

65534 65536
820462503 674023407 678774031 936839760 967886021 931679487 453790312 457688550 70497701 344893727 154301715 507005683 73026386 390834155 323019588 839428562 139619227 778200763 402648418 434214668 203135761 709945633 736891475 834231887 757898689 714927300 773615727 495008913 178272181 ...

output:

3556992
16638524
17773272
4500556
15023833
15616791
16530231
2941967
3166188
12186952
18098140
476862
4445062
9237154
8863687
143980
14070479
6047549
7425512

result:

ok 19 lines

Test #6:

score: 0
Accepted
time: 1698ms
memory: 26880kb

input:

65536 65536
405634173 17394581 118925347 922474073 743773645 237837181 499268357 244246848 939786401 792695975 628358275 678027475 348815741 419958879 726832416 24340945 901834373 56505761 405488783 771756785 890119785 252669240 492790889 529308875 31501425 546890993 105451499 269507525 583855527 42...

output:

14813680
12244780
5372831
129044
15936400
19557428
17514428
4965101
11035792
17705809
19062063
9585446
1382379
17154907
17605748
17161957
6292833
16315460
11100885
4587223

result:

ok 20 lines

Subtask #3:

score: 20
Accepted

Dependency #2:

100%
Accepted

Test #7:

score: 20
Accepted
time: 983ms
memory: 27024kb

input:

65536 65533
30932122 78382923 537901462 43608430 743690928 918369886 474585919 91526068 574096807 937639556 275209310 841686338 356806157 792932071 603518094 832348491 468678335 713509816 101484129 852321989 436384847 445099357 227895189 501297162 399636691 271485365 207312863 509602081 865283531 19...

output:

1496564
9125549
16577986
6310026
1063976
16707
52957
14908581
14790251
14722135
13755277
11137460
5968935
8549164
18541922
24957
1930126
16330833
14364850
2239625
10619499
16538
6589616
2426893
19692596
19164930
15643210
18580925
12236638
6881655
2537792
9181
5316249
16956425
5578816
5938013
7323269...

result:

ok 45533 lines

Test #8:

score: 0
Accepted
time: 1311ms
memory: 26764kb

input:

65536 65535
896327463 680912869 425088586 463001926 222746654 139797223 797862825 191243957 970951057 833986727 442405892 825555128 314556958 914737211 212060430 912767901 453296903 873665049 564716803 471005323 213780115 573452539 543739081 881018559 902197811 297810647 51022403 757374500 594296052...

output:

3765898
7160189
1840871
8384498
12162436
17733710
213192
867756
9465798
5355255
9688576
14003307
3802366
3494697
2813852
18250238
14202178
3534428
4309535
12426295
20119652
19552024
19554541
276659
9217790
4968412
4966695
8795674
14327484
5321111
5143428
4804826
14976742
1065939
6768277
11126616
392...

result:

ok 25535 lines

Test #9:

score: 0
Accepted
time: 693ms
memory: 27416kb

input:

65536 65536
273612167 315772190 71207511 736212317 523695534 424195293 720590001 84825693 594307129 913990193 946510345 222887460 962253802 124933747 293256949 752514778 915822505 86321273 339054171 563974341 489916343 956984316 111089551 70521376 292460752 45000461 214783067 288398507 49055118 1032...

output:

8409099
627948
11730380
8939261
10928253
17059110
6990391
13342784
4902327
5950655
16232329
8204509
19093841
4451012
18709415
3229726
10846229
5082475
17190005
14833410
5282247
2331065
10279617
4557434
7700054
8071957
10999644
1165013
95904
113129
12805875
15919700
10967571
3128343
12049502
18201862...

result:

ok 55536 lines

Subtask #4:

score: 0
Time Limit Exceeded

Dependency #1:

100%
Accepted

Dependency #2:

100%
Accepted

Dependency #3:

100%
Accepted

Test #10:

score: 0
Time Limit Exceeded

input:

65536 65536
690710135 657115917 211163039 197295969 367013816 156855111 797052165 886430858 508869157 17134147 61796741 347521885 250213399 668920827 220381843 208336869 792057463 245539955 861408575 952059033 360332858 249610287 456737865 567698963 120715589 263131517 574343202 122801665 999840299 ...

output:


result:


Subtask #5:

score: 0
Skipped

Dependency #1:

100%
Accepted

Dependency #2:

100%
Accepted

Dependency #3:

100%
Accepted

Dependency #4:

0%