莫队玄学 40 pts 求助
查看原帖
莫队玄学 40 pts 求助
688783
SilverLi楼主2023/12/21 14:53
#include <iostream>
#include <algorithm>
#include <utility>
#include <vector>
#include <cmath>
#include <stack>
#define p first
#define col second
#define int long long
using namespace std;
inline int read()
{
    int ans = 0, f = 0;
    char c = getchar();
    while (!isdigit(c))
        f |= (c == '-'), c = getchar();
    while (isdigit(c))
        ans = (ans << 3) + (ans << 1) + c - 48, c = getchar();
    return f ? -ans : ans;
}
void write(int x)
{
    if (x < 0)
        putchar('-'), x = -x;
    if (x > 9)
        write(x / 10);
    putchar(48 + x % 10);
}
const int N = 2e5 + 5;
int n, m, Q, sq;
int block, bl[N];
int v[N], w[N], res[N];
stack<int> sta;
struct que
{
    int u, v, ti, id;
    bool operator<(const que &x) const
    {
        if (bl[u] != bl[x.u])
            return bl[u] < bl[x.u];
        if (bl[v] != bl[x.v])
            return bl[v] < bl[x.v];
        return ti < x.ti;
    }
} q[N];
pair<int, int> t[N];
int tot, now, c[N], vis[N];
vector<int> g[N];
int son[N], dfn[N], top[N];
int si[N], cnt, fa[N], d[N];
void dfs1(int u, int ft)
{
    si[u] = 1, fa[u] = ft;
    d[u] = d[ft] + 1;
    int last = sta.size();
    for (int l = 0; l < g[u].size(); ++l)
    {
        int i = g[u][l];
        if (i != ft)
        {
            dfs1(i, u);
            si[u] += si[i];
            if (si[i] > si[son[u]])
                son[u] = i;
            if (sta.size() - last >= sq)
            {
                ++block;
                while (sta.size() > last)
                    bl[sta.top()] = block, sta.pop();
            }
        }
    }
    sta.push(u);
}
void dfs2(int u, int deep)
{
    top[u] = deep;
    dfn[u] = ++cnt;
    if (!son[u])
        return;
    dfs2(son[u], deep);
    for (int l = 0; l < g[u].size(); ++l)
    {
        int i = g[u][l];
        if (i != fa[u] && i != son[u])
            dfs2(i, i);
    }
}
inline int LCA(int u, int v)
{
    while (top[u] != top[v])
    {
        if (d[top[u]] < d[top[v]])
            swap(u, v);
        u = fa[top[u]];
    }
    if (d[u] > d[v])
        swap(u, v);
    return u;
}
int ans, mp[N];
inline void add(int col)
{
    ans += v[col] * w[++mp[col]];
}
inline void del(int col)
{
    ans -= v[col] * w[mp[col]--];
}
inline void change(int u)
{
    if (vis[u])
        del(c[u]);
    else
        add(c[u]);
    vis[u] ^= 1;
}
inline void move(int u, int v)
{
    while (d[u] != d[v])
    {
        if (d[u] < d[v])
            swap(u, v);
        change(u), u = fa[u];
    }
    while (u != v)
    {
        change(u), change(v);
        u = fa[u], v = fa[v];
    }
}
inline void time(int ti)
{
    if (vis[t[ti].p])
    {
        del(c[t[ti].p]);
        add(t[ti].col);
    }
    swap(c[t[ti].p], t[ti].col);
}
signed main()
{
    n = read(), m = read(), Q = read();
    sq = pow(n, 2.0 / 3.0);
    for (int i = 1; i <= m; ++i)
        v[i] = read();
    for (int i = 1; i <= n; ++i)
        w[i] = read();
    for (int i = 1; i < n; ++i)
    {
        int u = read(), v = read();
        g[u].emplace_back(v);
        g[v].emplace_back(u);
    }
    for (int i = 1; i <= n; ++i)
        c[i] = read();
    for (int i = 1; i <= Q; ++i)
        if (read())
        {
            ++tot;
            q[tot] = {read(), read(), now, tot};
        }
        else
            t[++now] = {read(), read()};
    dfs1(1, 0);
    // 	++block;
    while (!sta.empty())
        bl[sta.top()] = block, sta.pop();
    dfs2(1, 1);
    sort(q + 1, q + tot + 1);
    int u = 1, v = 1, ti = 0;
    change(1);
    for (int i = 1; i <= tot; ++i)
    {
        if (ti < q[i].ti)
            time(++ti);
        if (ti > q[i].ti)
            time(ti--);
        change(LCA(u, v));
        if (u != q[i].u)
            move(u, q[i].u), u = q[i].u;
        if (v != q[i].v)
            move(v, q[i].v), v = q[i].v;
        change(LCA(u, v));
        res[q[i].id] = ans;
    }
    for (int i = 1; i <= tot; ++i)
        write(res[i]), putchar('\n');
    return 0;
}
2023/12/21 14:53
加载中...