結果
| 問題 |
No.2342 Triple Tree Query (Hard)
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2024-11-28 15:31:01 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 3,226 ms / 10,000 ms |
| コード長 | 6,902 bytes |
| コンパイル時間 | 1,665 ms |
| コンパイル使用メモリ | 101,524 KB |
| 最終ジャッジ日時 | 2025-02-25 06:21:48 |
|
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 36 |
ソースコード
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <tuple>
using namespace std;
using i32 = int;
using i64 = long long;
using u32 = unsigned int;
using u64 = unsigned long long;
template<typename T> using vec = vector<T>;
using pii = pair<u32, u32>;
const u32 P = 998244353;
struct mint
{
u32 val;
mint(): val() { }
mint(u32 x): val(x) { }
mint &operator+=(mint t)
{
val += t.val;
if (val >= P) val -= P;
return *this;
}
mint &operator-=(mint t)
{
if (val < t.val) val += P;
val -= t.val;
return *this;
}
mint &operator*=(mint t)
{
val = (u64)val * t.val % P;
return *this;
}
friend mint operator+(mint a, mint b) { return a += b; }
friend mint operator-(mint a, mint b) { return a -= b; }
friend mint operator*(mint a, mint b) { return a *= b; }
mint pow(u32 y)
{
u64 res = 1, x = val;
for (; y; y >>= 1) {
if (y & 1) res = res * x % P;
x = x * x % P;
}
return mint(res);
}
mint inv() { return pow(P - 2); }
friend bool operator==(mint a, mint b) { return a.val == b.val; }
};
bool pairle(const pii &x, const pii &y)
{
return x.first <= y.first && x.second <= y.second;
}
pii pairmin(const pii &x, const pii &y)
{
return {min(x.first, y.first), min(x.second, y.second)};
}
pii pairmax(const pii &x, const pii &y)
{
return {max(x.first, y.first), max(x.second, y.second)};
}
template<typename M>
struct KDTree
{
using A = typename M::S;
u32 n;
vec<u32> rnk;
struct Node
{
pii sp, ep;
Node(): sp(), ep() { }
Node(const pii &a): sp(a), ep(a) { }
};
vec<A> t;
vec<Node> d;
KDTree(u32 _n, const vec<pii> &p): n(_n), rnk(n)
{
u32 m = 1;
while (m < n) m = m * 2;
t.resize(m * 2, M::un());
d.resize(m * 2);
vec<u32> idx(n);
for (u32 i = 0; i < n; i++) idx[i] = i;
build<0>(p, idx, 0, n, 1);
}
template<u32 D>
void build(const vec<pii> &p, vec<u32> &idx, u32 l, u32 r, u32 x)
{
if (l + 1 == r) {
u32 id = idx[l];
d[x] = p[id];
rnk[id] = l;
return ;
}
u32 mid = (l + r) >> 1;
nth_element(idx.data() + l, idx.data() + mid, idx.data() + r,
[&](u32 x, u32 y) {return std::get<D>(p[x]) < std::get<D>(p[y]);});
build<!D>(p, idx, l, mid, x * 2);
build<!D>(p, idx, mid, r, x * 2 + 1);
d[x].sp = pairmin(d[x * 2].sp, d[x * 2 + 1].sp);
d[x].ep = pairmax(d[x * 2].ep, d[x * 2 + 1].ep);
}
void push_down(u32 x)
{
if (t[x] != M::un()) {
M::oop(t[x * 2], t[x]);
M::oop(t[x * 2 + 1], t[x]);
t[x] = M::un();
}
}
void apply(const pii &st, const pii &ed, const A &a)
{
apply_rec(st, ed, a, 0, n, 1);
}
A get(u32 x)
{
return get_rec(rnk[x], 0, n, 1);
}
void apply_rec(const pii &st, const pii &ed, const A &a,
u32 l, u32 r, u32 x)
{
if (pairle(st, d[x].sp) && pairle(d[x].ep, ed)) {
M::oop(t[x], a);
return ;
}
if (!pairle(st, d[x].ep) || !pairle(d[x].sp, ed)) return ;
u32 mid = (l + r) >> 1;
push_down(x);
apply_rec(st, ed, a, l, mid, x * 2);
apply_rec(st, ed, a, mid, r, x * 2 + 1);
}
A get_rec(u32 p, u32 l, u32 r, u32 x)
{
if (l + 1 == r) return t[x];
u32 mid = (l + r) >> 1;
push_down(x);
if (p < mid) return get_rec(p, l, mid, x * 2);
return get_rec(p, mid, r, x * 2 + 1);
}
};
struct MonoidAffine
{
using S = pair<mint, mint>;
static void oop(S &a, const S &b)
{
a.first *= b.first;
(a.second *= b.first) += b.second;
}
static S un() { return {1, 0}; }
};
signed main()
{
// freopen("tour.in", "r", stdin);
// freopen("tour.out", "w", stdout);
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
u32 n, q;
cin >> n >> q;
vec<vec<u32>> g(n);
for (u32 i = 1, u, v; i < n; i++) {
cin >> u >> v;
--u, --v;
g[u].emplace_back(v);
g[v].emplace_back(u);
}
vec<mint> a(n);
for (u32 i = 0, x; i < n; i++) {
cin >> x;
a[i] = x;
}
vec<u32> dfn(n), rnk(n), dep(n), fa(n), dfnr(n), top(n), son(n, -1);
u32 dfnn = 0;
[&, dfs = [&](auto &&f, u32 x) -> void
{
dfn[x] = 1;
for (u32 v: g[x]) if (v != fa[x]) {
fa[v] = x;
dep[v] = dep[x] + 1;
f(f, v);
dfn[x] += dfn[v];
if (son[x] == -1u || dfn[v] > dfn[son[x]]) son[x] = v;
}
}](){dfs(dfs, 0);}();
[&, dfs = [&](auto &&f, u32 x) -> void
{
dfn[x] = dfnn;
rnk[dfnn++] = x;
if (son[x] != -1u) {
top[son[x]] = top[x];
f(f, son[x]);
}
for (u32 v: g[x]) if (v != fa[x] && v != son[x]) {
top[v] = v;
f(f, v);
}
dfnr[x] = dfnn - 1;
}](){dfs(dfs, 0);}();
vec<pii> initp(n);
for (u32 i = 0; i < n; i++) initp[i] = {dfn[i], dep[i]};
KDTree<MonoidAffine> t(n, initp);
while (q--) {
u32 op;
cin >> op;
if (op == 1) {
u32 x;
cin >> x;
--x;
auto xx = t.get(x);
cout << (xx.first * a[x] + xx.second).val << '\n';
}
else if (op == 4) {
u32 x, y, k, b;
cin >> x >> y >> k >> b;
--x, --y;
pair<mint, mint> val(k, b);
while (top[x] != top[y]) {
if (dep[top[x]] < dep[top[y]]) swap(x, y);
t.apply({dfn[top[x]], 0}, {dfn[x], n}, val);
x = fa[top[x]];
}
if (dep[x] > dep[y]) swap(x, y);
t.apply({dfn[x], 0}, {dfn[y], n}, val);
}
else if (op == 3) {
u32 x, k, b;
cin >> x >> k >> b;
--x;
t.apply({dfn[x], 0}, {dfnr[x], n}, {k, b});
}
else {
u32 x, r, k, b;
cin >> x >> r >> k >> b;
--x;
mint kk(mint(k).inv());
pair<mint, mint> val(k, b), ival(kk, mint(0) - kk * b);
t.apply({dfn[x], dep[x]}, {dfnr[x], dep[x] + r}, val);
while (r-- && x != 0) {
if (r >= 1 && k != 0) {
t.apply({dfn[x], dep[x]},
{dfnr[x], dep[x] + r - 1}, ival);
}
x = fa[x];
t.apply({dfn[x], dep[x]}, {dfnr[x], dep[x] + r}, val);
}
}
}
return 0;
}