QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#608655 | #9373. Query on Tree | UltramanBlazer | WA | 34ms | 3896kb | C++20 | 10.5kb | 2024-10-04 00:34:26 | 2024-10-04 00:34:26 |
Judging History
answer
#include <bits/stdc++.h>
using ll = long long;
using uint = unsigned int;
using ull = unsigned long long;
#define lowbit(x) (x & (-x))
const int mod = 998244353;
const double PI = 3.14159265358;
std::mt19937 rng(std::random_device{}());
namespace FI
{
char B[1 << 16], *S = B, *T = B;
inline char getc()
{
return S == T && (T = (S = B) + fread(B, 1, 1 << 16, stdin), S == T) ? EOF : *S++;
}
inline void read()
{
}
template <typename Tp, typename... Types>
inline void read(Tp &o, Types &...Args)
{
o = 0;
bool s = 0;
char c = getc();
while (c > '9' || c < '0')
s |= c == '-', c = getc();
while (c >= '0' && c <= '9')
o = o * 10 + c - '0', c = getc();
if (s)
o = -o;
read(Args...);
}
} // namespace FI
using FI::read;
constexpr int MultiTestCases = 1;
constexpr ll INF = 1e18, threshold = 1e15;
struct Info
{
ll mx = -INF;
};
Info operator+(const Info &a, const Info &b)
{
Info res;
res.mx = std::max(a.mx, b.mx);
return res;
}
struct Tag
{
ll delta = 0;
};
struct T
{
ll delta = 0;
};
T operator+(const T &a, const T &b)
{
return {a.delta + b.delta};
}
Info operator+(const Info &a, const T &b)
{
Info res;
res.mx = a.mx + b.delta;
return res;
}
void apply(T &a, const Tag &b)
{
if (b.delta != 0)
a.delta += b.delta;
}
void apply(Info &a, const Tag &b)
{
if (b.delta != 0)
a.mx += b.delta;
}
void apply(Tag &a, const Tag &b)
{
if (b.delta != 0)
a.delta += b.delta;
}
template <typename Info, typename Tag, typename Merge = std::plus<Info>>
struct LazySegmentTree
{
const int n;
const Merge merge;
struct node
{
Info info;
Tag tag;
};
std::vector<node> tree;
LazySegmentTree(int _n) : n(_n), merge(Merge()), tree(_n * 4 + 5)
{
}
LazySegmentTree(std::vector<Info> &init, int _n) : LazySegmentTree(_n)
{
std::function<void(int, int, int)> build = [&](int p, int l, int r)
{
if (l == r)
{
tree[p].info = init[l];
return;
}
int mid = (l + r) / 2;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
pull(p);
};
build(1, 1, n);
}
void pull(int p)
{
tree[p].info = merge(tree[p << 1].info, tree[p << 1 | 1].info);
}
void apply(int p, const Tag &v)
{
::apply(tree[p].info, v);
::apply(tree[p].tag, v);
}
void push(int p)
{
apply(p << 1, tree[p].tag);
apply(p << 1 | 1, tree[p].tag);
tree[p].tag = Tag();
}
void modify(int p, int l, int r, int x, const Info &v)
{
if (l == r)
return tree[p].info = v, void();
int mid = (l + r) >> 1;
push(p);
if (x <= mid)
modify(p << 1, l, mid, x, v);
else
modify(p << 1 | 1, mid + 1, r, x, v);
pull(p);
}
void modify(int p, const Info &v)
{
modify(1, 1, n, p, v);
}
Info query(int p, int l, int r, int x, int y)
{
if (l == x && r == y)
return tree[p].info;
int mid = (l + r) >> 1;
push(p);
if (y <= mid)
return query(p << 1, l, mid, x, y);
else if (x > mid)
return query(p << 1 | 1, mid + 1, r, x, y);
else
return merge(query(p << 1, l, mid, x, mid), query(p << 1 | 1, mid + 1, r, mid + 1, y));
}
Info query(int l, int r)
{
return query(1, 1, n, l, r);
}
void apply(int p, int l, int r, int x, int y, const Tag &v)
{
if (l == x && r == y)
{
apply(p, v);
return;
}
int mid = (l + r) >> 1;
push(p);
if (y <= mid)
apply(p << 1, l, mid, x, y, v);
else if (x > mid)
apply(p << 1 | 1, mid + 1, r, x, y, v);
else
apply(p << 1, l, mid, x, mid, v), apply(p << 1 | 1, mid + 1, r, mid + 1, y, v);
pull(p);
}
void apply(int l, int r, const Tag &v)
{
if (l > r)
return;
return apply(1, 1, n, l, r, v);
}
};
int Main()
{
int n, q;
read(n, q);
std::vector<ll> a(n + 1);
for (int i = 1; i <= n; ++i)
read(a[i]);
std::vector fa(n + 1, std::array<int, 11>{});
std::vector adj(n + 1, std::vector<int>{});
for (int i = 1; i < n; ++i)
{
int u, v;
read(u, v);
adj[u].push_back(v);
adj[v].push_back(u);
}
std::vector<int> bfseq{0};
std::vector bfs_in(n + 1, std::array<std::pair<int, int>, 11>{});
auto bfs = [&]()
{
for (int i = 1; i <= n; ++i)
bfs_in[i].fill(std::pair{n + 1, 0});
std::queue<int> q;
q.push(1);
while (!q.empty())
{
int u = q.front();
q.pop();
bfseq.push_back(u);
if (fa[u][1] != 0)
adj[u].erase(std::find(adj[u].begin(), adj[u].end(), fa[u][1]));
for (int v : adj[u])
{
fa[v][1] = u;
for (int d = 2; d <= 10; ++d)
fa[v][d] = fa[u][d - 1];
q.push(v);
}
}
for (int i = 1; i <= n; ++i)
{
int u = bfseq[i];
for (int d = 1; d <= 10; ++d)
{
int p = fa[u][d];
bfs_in[p][d].first = std::min(i, bfs_in[p][d].first);
bfs_in[p][d].second = std::max(i, bfs_in[p][d].second);
}
bfs_in[u][0] = {i, i};
}
};
bfs();
std::vector<int> in(n + 1), out(n + 1), dfseq{0};
auto dfs = [&](auto &&self, int u) -> void
{
in[u] = dfseq.size();
dfseq.push_back(u);
for (int v : adj[u])
self(self, v);
out[u] = dfseq.size() - 1;
};
dfs(dfs, 1);
std::vector<Info> init_bfs(n + 1);
std::vector<Info> init_dfs(n + 1);
for (int i = 1; i <= n; ++i)
init_bfs[i] = {a[bfseq[i]]};
for (int i = 1; i <= n; ++i)
if (fa[i][10] != 0)
{
int u = fa[i][10];
init_dfs[in[u]] = init_dfs[in[u]] + Info{a[i]};
}
LazySegmentTree<Info, Tag> bfs_seg_tree(init_bfs, n);
LazySegmentTree<T, Tag> tag_seg_tree(n);
LazySegmentTree<Info, Tag> dfs_seg_tree(init_dfs, n);
auto update = [&](int l, int r, int v)
{
bfs_seg_tree.apply(l, r, {v});
int p = fa[bfseq[l]][10];
if (!p)
return;
auto [lp, rp] = bfs_in[p][10];
Info tmp = bfs_seg_tree.query(lp, rp) + tag_seg_tree.query(in[p], in[p]);
dfs_seg_tree.modify(in[p], tmp);
};
auto query = [&](int l, int r)
{
Info tmp = bfs_seg_tree.query(l, r);
int p = fa[bfseq[l]][10];
if (!p)
return tmp;
else
return tmp + tag_seg_tree.query(in[p], in[p]);
};
auto qry1 = [&](int u, int d, int v) -> Info
{
int x = u, y = 0;
Info ans{-INF};
for (int i = 0; i <= d; ++i, y = x, x = fa[x][1])
{
if (!x)
break;
auto [l, r] = bfs_in[x][d - i];
if (!r)
continue;
if (!y)
{
update(l, r, v);
ans = ans + query(l, r);
}
else if (i < d && y)
{
auto [p, q] = bfs_in[y][d - i - 1];
if (l < p)
{
update(l, p - 1, v);
ans = ans + query(l, p - 1);
}
if (q < r)
{
update(q + 1, r, v);
ans = ans + query(q + 1, r);
}
}
}
return ans;
};
auto qry2 = [&](int u, int d, int v) -> Info
{
int x = u, y = 0, cur = d + 1;
Info ans{-INF};
for (int i = 0; i <= d; ++i, y = x, x = fa[x][1] ? fa[x][1] : x)
{
if ((y != x || d - i < cur))
{
auto [l, r] = bfs_in[x][d - i];
if (l <= r)
{
update(l, r, v);
ans = ans + query(l, r);
cur = d - i;
}
}
if ((y != x || d - i - 1 < cur) && d - i - 1 >= 0)
{
auto [l, r] = bfs_in[x][d - i - 1];
if (l <= r)
{
update(l, r, v);
ans = ans + query(l, r);
cur = d - i - 1;
}
}
}
return ans;
};
auto qry3 = [&](int u, int v) -> Info
{
Info ans{-INF};
for (int i = 0; i < 10; ++i)
{
auto [l, r] = bfs_in[u][i];
if (l <= r)
{
update(l, r, v);
ans = ans + query(l, r);
}
}
dfs_seg_tree.apply(in[u], out[u], {v});
tag_seg_tree.apply(in[u], out[u], {v});
ans = ans + dfs_seg_tree.query(in[u], out[u]);
return ans;
};
while (q--)
{
int op;
read(op);
if (op == 3)
{
int u, v;
read(u, v);
Info res = qry3(u, v);
if (res.mx < -threshold)
printf("GG\n");
else
printf("%lld\n", res.mx);
continue;
}
int u, v, d;
read(u, d, v);
if (op == 1)
{
Info res = qry1(u, d, v);
if (res.mx < -threshold)
printf("GG\n");
else
printf("%lld\n", res.mx);
}
else if (op == 2)
{
Info res = qry2(u, d, v);
if (res.mx < -threshold)
printf("GG\n");
else
printf("%lld\n", res.mx);
}
}
return 0;
}
int main()
{
int TestCases = 1;
if constexpr (MultiTestCases == 1)
scanf("%d", &TestCases);
while (TestCases--)
Main();
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 1ms
memory: 3840kb
input:
1 5 5 1 2 1 3 2 1 2 2 3 2 4 4 5 2 2 1 0 1 2 1 3 3 4 -5 2 5 2 3 3 2 -1
output:
3 6 1 5 4
result:
ok 5 lines
Test #2:
score: -100
Wrong Answer
time: 34ms
memory: 3896kb
input:
10000 3 9 42973045452542 34994498886390 -91733395797555 1 3 1 2 1 1 5 -71952967 3 1 -816873082 1 1 5 -842437577 2 3 7 254550528 3 3 -854082700 2 3 2 699808309 3 3 554885567 1 2 7 595565507 1 3 0 -318374053 3 2 -63158159333100 77264362049163 -99188430131116 1 2 3 2 2 2 4 -305866230 3 1 -549738403 3 5...
output:
GG 42972228579460 GG 42972483129988 -91734812202809 42973182938297 -91733557508933 GG -91733875882986 77264056182933 77263506444530 7065382376488 7065749360235 7066534912965 -85115611272570 -85114714781312 96492412785032 -20428913156111 -20428197540063 96491742171666 -14945310996805 96491180203461 -...
result:
wrong answer 28th lines differ - expected: '98376029853540', found: 'GG'