WA 90 求助!玄关
查看原帖
WA 90 求助!玄关
300098
cmaths楼主2023/12/28 21:39
#include <bits/stdc++.h>
#define int long long

using namespace std;

int read()
{
    int x = 0, f = 1;
    char ch = 0;
    while(!isdigit(ch))
    {
        if(ch == '-')
        {
            f = -1;
        }
        ch = getchar();
    }
    while(isdigit(ch))
    {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

const int N = 100000, Q = 500000, LG = 20, B = 100;
int n, q;
int a[N + 5], lsa[N + 5], fz[N + 5];

struct Edge
{
    int v, nxt;
}edge[N * 2 + 5];
int head[N + 5], cnte;
void adde(int u, int v)
{
    edge[++cnte] = {v, head[u]};
    head[u] = cnte;
}

int dfn[N + 5], siz[N + 5], cntn;
int fa[N + 5][LG + 5], dep[N + 5];
int rk[N + 5];
void dfs(int u, int fath)
{
    dep[u] = dep[fath] + 1;
    dfn[u] = ++cntn;
    siz[u] = 1;
    rk[cntn] = u;
    fa[u][0] = fath;
    for(int i = 1; i <= LG; i++)
    {
        fa[u][i] = fa[fa[u][i - 1]][i - 1];
    }
    for(int i = head[u]; i; i = edge[i].nxt)
    {
        int v = edge[i].v;
        if(v == fath)
        {
            continue;
        }
        dfs(v, u);
        siz[u] += siz[v];
    }
}
int LCA(int x, int y)
{
    if(dep[x] < dep[y])
    {
        swap(x, y);
    }
    for(int i = LG; i >= 0; i--)
    {
        if(dep[fa[x][i] >= dep[y]])
        {
            x = fa[x][i];
        }
    }
    if(x == y)
    {
        return x;
    }
    for(int i = LG; i >= 0; i--)
    {
        if(fa[x][i] != fa[y][i])
        {
            x = fa[x][i], y = fa[y][i];
        }
    }
    return fa[x][0];
}
int get(int x, int y)
{
    for(int i = LG; i >= 0; i--)
    {
        if(dep[fa[x][i]] > dep[y])
        {
            x = fa[x][i];
        }
    }
    return x;
}

int ans[Q + 5];
bool is[Q + 5];
int get(int x)
{
    return (x + B - 1) / B;
}
struct Qu
{
    int r1, r2;
    int ans, id, f;
    bool operator < (const Qu &t) const
    {
        if(get(r1) != get(t.r1))
        {
            return get(r1) < get(t.r1);
        }
        if(get(r1) % 2)
        {
            return r2 < t.r2;
        }
        else
        {
            return r2 > t.r2;
        }
    }
}qu[Q * 4 + 5];
int cntqu;
int cur;
int cnt1[N + 5], cnt2[N + 5];
void add1(int x)
{
    cur += cnt2[lsa[rk[x]]];
    cnt1[lsa[rk[x]]]++;
}
void del1(int x)
{
    cur -= cnt2[lsa[rk[x]]];
    cnt1[lsa[rk[x]]]--;
}
void add2(int x)
{
    cur += cnt1[lsa[rk[x]]];
    cnt2[lsa[rk[x]]]++;
}
void del2(int x)
{
    cur -= cnt1[lsa[rk[x]]];
    cnt2[lsa[rk[x]]]--;
}
void mo()
{
    int r1 = 0, r2 = 0;
    for(int i = 1; i <= cntqu; i++)
    {
        while(r1 < qu[i].r1)
        {
            add1(++r1);
        }
        while(r2 < qu[i].r2)
        {
            add2(++r2);
        }
        while(r1 > qu[i].r1)
        {
            del1(r1--);
        }
        while(r2 > qu[i].r2)
        {
            del2(r2--);
        }
        ans[qu[i].id] += cur * qu[i].f;
        // printf("%lld %lld %lld\n", qu[i].r1, qu[i].r2, cur);
    }
}

void init()
{
    n = read(), q = read();
    for(int i = 1; i <= n; i++)
    {
        a[i] = read();
        fz[i] = a[i];
    }
    sort(fz + 1, fz + n + 1);
    for(int i = 1; i <= n; i++)
    {
        lsa[i] = lower_bound(fz + 1, fz + n + 1, a[i]) - fz;
    }
    for(int i = 1; i < n; i++)
    {
        int u = read(), v = read();
        adde(u, v);
        adde(v, u);
    }
    dfs(1, 0);
}

int tot[N + 5];
int awa;
int calca[N + 5];
int rt;
void solve()
{
    // for(int i = 1; i <= n; i++)
    // {
    //     printf("%lld ", lsa[i]);
    // }
    // printf("\n");
    // for(int i = 1; i <= n; i++)
    // {
    //     printf("%lld ", dfn[i]);
    // }
    // printf("\n");
    for(int i = 1; i <= n; i++)
    {
        tot[lsa[i]]++;
    }
    for(int i = 1; i <= n; i++)
    {
        awa += tot[i] * tot[i];
    }
    for(int i = 1; i <= n; i++)
    {
        calca[i] = calca[i - 1] + tot[lsa[rk[i]]];
    }
    // for(int i = 1; i <= n; i++)
    // {
    //     printf("%lld ", calca[i]);
    // }
    // printf("\n");
    rt = 1;
    for(int i = 1; i <= q; i++)
    {
        int op = read();
        if(op == 1)
        {
            rt = read();
        }
        else
        {
            is[i] = 1;
            int x = read(), y = read();
            int lcax = LCA(x, rt), lcay = LCA(y, rt);
            int lx, rx;
            int f = 1;
            int cnt = 0, tmp = 0;
            if(x != rt)
            {
                if(lcax != x)
                {
                    lx = dfn[x] - 1, rx = dfn[x] + siz[x] - 1;
                }
                else
                {
                    int g = get(rt, x);
                    lx = dfn[g] - 1, rx = dfn[g] + siz[g] - 1;
                    f *= -1;
                    cnt++;
                    tmp = 1;
                }
            }
            else
            {
                lx = 0, rx = n;
            }
            int ly, ry;
            if(y != rt)
            {
                if(lcay != y)
                {
                    ly = dfn[y] - 1, ry = dfn[y] + siz[y] - 1;
                }
                else
                {
                    int g = get(rt, y);
                    ly = dfn[g] - 1, ry = dfn[g] + siz[g] - 1;
                    f *= -1;
                    cnt++;
                    tmp = 2;
                }
            }
            else
            {
                ly = 0, ry = n;
            }
            if(cnt == 1)
            {
                if(tmp == 1)
                {
                    ans[i] += calca[ry] - calca[ly];
                }
                else
                {
                    ans[i] += calca[rx] - calca[lx];
                }
            }
            else if(cnt == 2)
            {
                ans[i] -= calca[rx] - calca[lx];
                ans[i] -= calca[ry] - calca[ly];
                ans[i] += awa;
            }
            qu[++cntqu] = {lx, ly, 0, i, f};
            qu[++cntqu] = {lx, ry, 0, i, -f};
            qu[++cntqu] = {rx, ly, 0, i, -f};
            qu[++cntqu] = {rx, ry, 0, i, f};
            // printf("%lld %lld %lld %lld %lld\n", lx, rx, ly, ry, f);
        }
    }
    sort(qu + 1, qu + cntqu + 1);
    mo();
    for(int i = 1; i <= q; i++)
    {
        if(is[i])
        {
            printf("%lld\n", ans[i]);
        }
    }
}

signed main()
{
    // freopen("gen.out", "r", stdin);
    // freopen("my.out", "w", stdout);
    init();
    solve();
    return 0;
}//

awaqwq

2023/12/28 21:39
加载中...