QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#260390 | #7839. 虹 | hos_lyric# | 10 | 1757ms | 36888kb | C++14 | 22.2kb | 2023-11-22 07:09:09 | 2024-07-04 03:08:12 |
Judging History
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;
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<int> lpf(N + 1, 0);
vector<vector<int>> pss(N + 1);
for (int p = 2; p <= N; ++p) lpf[p] = p;
for (int p = 2; p <= N; ++p) if (lpf[p] == p) {
for (int n = p; n <= N; n += p) {
chmin(lpf[n], p);
pss[n].push_back(p);
}
}
vector<vector<int>> qss(N + 1);
for (int n = 1; n <= N; ++n) {
const auto &ps = pss[n];
auto &qs = qss[n];
const int psLen = ps.size();
qs.resize(1 << psLen);
qs[0] = n;
for (int i = 0; i < psLen; ++i) {
for (int h = 0; h < 1 << i; ++h) {
qs[h | 1 << i] = qs[h] / ps[i];
}
}
}
vector<vector<Mint>> fss(N + 1);
vector<vector<int>> dss(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) {
dss[d * e].push_back(d);
}
}
{
vector<Mint> work(N + 1, 0);
for (int u = 1; u <= N; ++u) {
const Mint s = S.pow(ws[u - 1]);
const auto &ds = dss[u];
const int dsLen = ds.size();
for (int i = 0; i < dsLen; ++i) {
work[ds[i]] = s.pow(ds[i]);
}
for (int i = dsLen; --i >= 0; ) {
for (int h = 1; h < (int)qss[ds[i]].size(); ++h) {
work[ds[i]] += (__builtin_parity(h)?-1:+1) * work[qss[ds[i]][h]];
}
}
for (int i = 0; i < dsLen; ++i) {
fss[ds[i]][u / ds[i]] += work[ds[i]];
work[ds[i]] = 0;
}
}
}
for (int d = 1; d <= N; ++d) {
const int len = N / d;
for (int e = 1; e <= len; ++e) {
fss[d][e] += fss[d][e - 1];
}
}
vector<Mint> anss;
for (int q = 0; q < Q; ++q) if (O[q] == 2) {
Mint ans = 0;
for (const int d : dss[T[q]]) {
ans += (fss[d][R[q] / d] - fss[d][L[q] / d]);
}
anss.push_back(ans);
}
return anss;
}
} // subA
int main() {
for (; ~scanf("%d%d", &N, &Q); ) {
Z.assign(N + 1, 0);
for (int x = 1; x <= N; ++x) {
scanf("%d", &Z[x]);
}
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;
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();
assert(brt==anss);
#endif
}
return 0;
}
详细
Subtask #1:
score: 10
Accepted
Test #1:
score: 10
Accepted
time: 29ms
memory: 4040kb
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: 26ms
memory: 3884kb
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: 25ms
memory: 3856kb
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: 0
Wrong Answer
Test #4:
score: 0
Wrong Answer
time: 1757ms
memory: 36888kb
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:
17763632 2422920 9648915 9098885 8961400 9404 11866041 11389224 10617349 4665775 3177635 15364675 2060686 14830895 19477828 19631288 13213237 11582479 12467078 7617315
result:
wrong answer 1st lines differ - expected: '2662122', found: '17763632'
Subtask #3:
score: 0
Skipped
Dependency #2:
0%
Subtask #4:
score: 0
Skipped
Dependency #1:
100%
Accepted
Dependency #2:
0%
Subtask #5:
score: 0
Skipped
Dependency #1:
100%
Accepted
Dependency #2:
0%