QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#91417 | #4381. Treasure | Tobo | AC ✓ | 1929ms | 89364kb | C++20 | 4.6kb | 2023-03-28 20:50:56 | 2023-03-28 20:50:58 |
Judging History
answer
#include <iostream>
#include <algorithm>
#include <vector>
#include <stack>
#define maxn 100010
#define Maxn 200010
#define maxm 200010
#define ll long long
#define lowbit(i) ((i) & (-i))
using namespace std;
int n, m, q, c[maxn];
vector<int> A[maxn];
ll s[Maxn];
struct node {
int fr, to, w;
friend bool operator < (const node &u, const node &v) { return u.w < v.w; }
} E[maxm];
int fa[Maxn];
void init_fa(int n) { for (int i = 1; i <= n; ++i) fa[i] = i; }
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
#define lc T[u].ch[0]
#define rc T[u].ch[1]
struct Tree {
int v, ch[2];
} T[Maxn]; int top, rt;
inline void init_tree(int n) {
for (int i = 1; i <= top; ++i)
T[i].v = T[i].ch[0] = T[i].ch[1] = 0;
top = n; rt = 2 * n - 1;
}
int dep[Maxn], f[Maxn][21], in[Maxn], out[Maxn], c2;
void pre(int u, int fa, int d) {
if (!u) return ;
dep[u] = d; f[u][0] = fa; in[u] = ++c2;
pre(lc, u, d + 1); pre(rc, u, d + 1);
out[u] = c2;
}
void init_lca(int n) {
for (int j = 1; j <= 20; ++j)
for (int i = 1; i <= n; ++i) f[i][j] = f[f[i][j - 1]][j - 1];
}
int get_lca(int x, int y) {
if (dep[x] < dep[y]) swap(x, y);
for (int i = 20; ~i; --i)
if (dep[f[x][i]] >= dep[y]) x = f[x][i];
if (x == y) return x;
for (int i = 20; ~i; --i)
if (f[x][i] ^ f[y][i]) x = f[x][i], y = f[y][i];
return f[x][0];
}
ll Bit[Maxn];
void add(int i, ll v) { while (i <= top) Bit[i] += v, i += lowbit(i); }
ll get_sum(int i) {
ll s = 0;
while (i) s += Bit[i], i -= lowbit(i);
return s;
}
int id[Maxn];
struct xushu {
static const int N = 25;
struct Edge {
int to, next;
} e[N]; int c1, head[N];
inline void add_edge(int u, int v) {
e[c1].to = v; e[c1].next = head[u]; head[u] = c1++;
}
int a[N], bl[N];
void solve(int col) {
int n = 0, top = 1; c1 = 0;
for (auto t : A[col]) a[++n] = t;
sort(a + 1, a + n + 1, [](const int &u, const int &v) { return in[u] < in[v]; });
id[rt] = top; bl[top] = rt;
for (int i = 1; i <= n; ++i) id[a[i]] = ++top, bl[top] = a[i];
for (int i = 1; i < N; ++i) head[i] = -1;
stack<int> S; S.push(rt);
for (int o = 1, u = a[o]; o <= n; u = a[++o]) {
if (u == rt) continue; int lca = get_lca(u, S.top());
while (S.top() != lca) {
int t = S.top(); S.pop();
if (in[S.top()] < in[lca]) id[lca] = ++top, bl[top] = lca, S.push(lca);
add_edge(id[S.top()], id[t]);
} S.push(u);
}
while (S.top() != rt) {
int t = S.top(); S.pop();
add_edge(id[S.top()], id[t]);
}
}
ll dfs(int u, int fa, int opt) {
ll mx = s[bl[u]], sum = 0;
for (int i = head[u]; ~i; i = e[i].next) {
int v = e[i].to; if (v == fa) continue;
ll val = dfs(v, u, opt); mx = max(mx, val); sum += val;
} add(in[bl[u]], opt * (mx - sum));
return mx;
}
} _T[maxn];
int jump(int x, int k) {
for (int i = 20; ~i; --i)
if (f[x][i] && T[f[x][i]].v <= k) x = f[x][i];
return x;
}
inline void solve_1() {
int x, y; cin >> x >> y;
_T[c[x]].dfs(1, 0, -1); s[x] += y; _T[c[x]].dfs(1, 0, 1);
}
inline void solve_2() {
int x, y; cin >> x >> y;
x = jump(x, y);
cout << get_sum(out[x]) - get_sum(in[x] - 1) << "\n";
}
void work() {
cin >> n >> m >> q;
c2 = 0; init_tree(n);
for (int i = 1; i < 2 * n; ++i) Bit[i] = 0;
for (int i = n + 1; i < 2 * n; ++i) s[i] = 0;
for (int i = 1; i <= n; ++i) A[i].clear();
for (int i = 1; i <= n; ++i) cin >> c[i], A[c[i]].push_back(i);
for (int i = 1; i <= n; ++i) cin >> s[i];
for (int i = 1; i <= m; ++i) cin >> E[i].fr >> E[i].to >> E[i].w;
sort(E + 1, E + m + 1); init_fa(2 * n - 1);
for (int i = 1; i <= m; ++i) {
int u = E[i].fr, v = E[i].to, w = E[i].w, fu, fv;
if ((fu = find(u)) == (fv = find(v))) continue;
fa[fu] = fa[fv] = ++top; T[top].ch[0] = fu; T[top].ch[1] = fv;
T[top].v = w;
} pre(rt, 0, 1); init_lca(top);
for (int i = 1; i <= n; ++i) {
_T[i].solve(i);
_T[i].dfs(1, 0, 1);
}
for (int i = 1; i <= q; ++i) {
int opt; cin >> opt;
if (opt == 0) solve_1();
else solve_2();
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
int T; cin >> T;
while (T--) work();
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 1929ms
memory: 89364kb
input:
5 100000 200000 100000 9290 4185 4966 4886 8843 6033 6979 8201 2305 2757 8296 7988 9228 6595 7582 6493 8427 4170 5054 9813 9196 5628 8707 9425 7632 4559 8841 4547 9120 2959 9696 7680 9848 7845 9978 9244 9021 1920 7331 9278 9969 8149 9608 8951 7695 9631 8327 4278 9674 9989 9494 7887 7676 5213 4831 88...
output:
860799337 882647427 881768794 896437709 708091348 698196612 891198837 904339854 896254269 902186690 73046 877403687 885140462 902762378 99017 907366777 900836408 892711537 900489867 36897 907937094 861445218 907195542 908810550 851522916 897351601 570500543 783111180 900316384 842886769 907103714 81...
result:
ok 250022 lines