MnZn求助,缩点+树上差分60pts,WA on #7、8、10,悬赏关注
查看原帖
MnZn求助,缩点+树上差分60pts,WA on #7、8、10,悬赏关注
470960
Yellow_and_Strong楼主2023/3/27 09:37

rt

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 5e5 + 50;
const int MAXM = 2e6 + 20;

inline int read()
{
    int x = 0; char ch = getchar();
    while (!isdigit(ch)) ch = getchar();
    while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch xor 48), ch = getchar();
    return x;
}
inline void write (int x)
{
    if (x > 9) write(x / 10);
    putchar (x % 10 + 48);
}

int n, m, a[MAXN], U[MAXM], V[MAXM];
struct Edge { int to, next; }e[(MAXM << 1) + (MAXN << 1)]; int head[MAXN << 1], cnt = 1;
inline void add (int u, int v) { e[++ cnt] = (Edge){v, head[u]}, head[u] = cnt; }
inline void input()
{
    n = read(), m = read();
    for (register int i = 1; i <= n; ++ i) a[i] = read();
    for (register int i = 1; i <= m; ++ i)
        U[i] = read(), V[i] = read(), add(U[i], V[i]), add(V[i], U[i]);
}

int inde, dfn[MAXN << 1], low[MAXN << 1]; bool vis[MAXN << 1]; stack <int> s;
int dcc_cnt, dcc[MAXN];
struct EDGE { int to, next; }E[MAXM << 1]; int Head[MAXN], Cnt; int sum[MAXN];
void Tarjan (int u, int last)
{
    vis[u] = true, dfn[u] = low[u] = ++ inde; s.push(u);
    for (register int i = head[u]; i; i = e[i].next)
    {
        int v = e[i].to;
        if (!vis[v])
        {
            Tarjan (v, i);
            low[u] = min(low[u], low[v]);
            if (low[v] > dfn[u])
            {
                ++ dcc_cnt; int uless;
                do { uless = s.top(); s.pop(); dcc[uless] = dcc_cnt, sum[dcc_cnt] += a[uless]; } while(uless != v);
            }
        }
        else if (i != (last ^ 1))
            low[u] = min(low[u], dfn[v]);
    }
}
inline void Add (int u, int v) { E[++ Cnt] = (EDGE){v, Head[u]}, Head[u] = Cnt; }
inline void ShP()
{
    for (register int i = 1; i <= n; ++ i)
        if (!vis[i]) inde = 0, add(i + n, i), add(i, i + n), Tarjan(i + n, 0);
    for (register int i = 1; i <= m; ++ i)
        if (dcc[U[i]] != dcc[V[i]]) Add(dcc[U[i]], dcc[V[i]]), Add(dcc[V[i]], dcc[U[i]]);
}

int fa[MAXN][31], d[MAXN];
void dfs_init (int u, int f)
{
    fa[u][0] = f, d[u] = d[f] + 1;
    for (register int i = Head[u]; i; i = E[i].next)
    {
        int v = E[i].to;
        if (v == f) continue;
        dfs_init (v, u);
    }
}

int q, ans, val[MAXN];
inline int LCA (int x, int y)
{
    if (d[x] > d[y]) swap(x, y);
    int tmp = d[y] - d[x];
    for (register int i = 0; tmp; ++ i, tmp >>= 1)
        if (tmp & 1) y = fa[y][i];
    if (x == y) return x;
    for (register int i = 30; i >= 0 and x != y; -- i)
        if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
    return fa[x][0];
}
void dfs (int u, int f)
{
    for (register int i = Head[u]; i; i = E[i].next)
    {
        int v = E[i].to;
        if (v == f) continue;
        dfs(v, u), val[u] += val[v];
    }
    if (val[u] > 0) ans += sum[u];
}
inline void work()
{
    q = read();
    while (q --)
    {
        int x = read(), y = read();
        x = dcc[x], y = dcc[y];
        int lca = LCA(x, y);
        ++ val[x], -- val[lca];
        ++ val[y], -- val[fa[lca][0]];
    }
    dfs (1, -1);
}

inline void output() { write(ans), putchar('\n'); }

int main()
{
    input();
    ShP();
    dfs_init (1, 0);
    work();
    output();
    return 0;
}
2023/3/27 09:37
加载中...