QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#91417#4381. TreasureToboAC ✓1929ms89364kbC++204.6kb2023-03-28 20:50:562023-03-28 20:50:58

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-03-28 20:50:58]
  • 评测
  • 测评结果:AC
  • 用时:1929ms
  • 内存:89364kb
  • [2023-03-28 20:50:56]
  • 提交

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