QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#708536#6127. Kawa Examphuong2222ML 3ms15944kbC++144.9kb2024-11-03 23:23:202024-11-03 23:23:21

Judging History

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

  • [2024-11-03 23:23:21]
  • 评测
  • 测评结果:ML
  • 用时:3ms
  • 内存:15944kb
  • [2024-11-03 23:23:20]
  • 提交

answer

#include<bits/stdc++.h>
using namespace std;
using lli = long long;
const int maxN = 1e5 + 5;
int n,m,c[maxN],id[maxN],sz[maxN],bc[maxN];
vector<int> adj[maxN],adjcc[maxN],node[maxN];
int d[maxN],d1[maxN],res = 0;
int num[maxN],low[maxN],t,cc,ans[maxN],cnt;
int idtr[maxN],eid[maxN];
bool avail[maxN];
priority_queue<pair<int,int>> q,q1;
struct Tedge
{
    int u,v,res;
    bool ch,flag;
}
e[maxN];
void reset()
{
    for (int i = 1;i <= n;++i)
    {
        adj[i].clear();
        adjcc[i].clear();
        node[i].clear();
        low[i] = num[i] = 0;
    }
}
void input()
{
    cin >> n >> m;
    reset();
    for (int i = 1;i <= n;++i)
    {
        cin >> c[i];
        d1[c[i]] = 0;
    }
    for (int i = 1;i <= m;++i)
    {
        cin >> e[i].u >> e[i].v;
        adj[e[i].u].push_back(i);
        adj[e[i].v].push_back(i);
        e[i].ch = false;
        e[i].flag = false;
    }
}
void dfs(int u)
{
    num[u] = low[u] = ++t;
    for (int i : adj[u])
    {
        if (e[i].flag) continue;
        int v = e[i].u ^ e[i].v ^ u;
        e[i].flag = true;
        if (num[v] == 0)
        {
            dfs(v);
            low[u] = min(low[u],low[v]);
            if (num[v] == low[v]) e[i].ch = true;
        }
        else low[u] = min(low[u],num[v]);
    }
}
void dfs1(int u)
{
    avail[u] = false;
    id[u] = cc;
    node[cc].push_back(u);
    for (int i : adj[u])
    {
        int v = e[i].u ^ e[i].v ^ u;
        if (avail[v] && !e[i].ch) dfs1(v);
    }
}
void presolve()
{
    t = 0;
    for (int i = 1;i <= n;++i)
    if (num[i] == 0) dfs(i);
    cc = 0;
    fill(avail + 1,avail + n + 1,true);
    for (int i = 1;i <= n;++i)
    {
        if (avail[i])
        {
            ++cc;
            dfs1(i);
        }
    }
    for (int i = 1;i <= m;++i)
    {
        if (e[i].ch)
        {
            adjcc[id[e[i].v]].push_back(i);
            adjcc[id[e[i].u]].push_back(i);
        }
    }
}
void addc(int v,int val)
{
    d[c[v]] += val;
    d1[c[v]] -= val;
    q.push({d[c[v]],c[v]});
    q1.push({d1[c[v]],c[v]});
}
void add(int u,int par,int val)
{
    for (int v : node[u]) addc(c[v],val);
    for (int i : adjcc[u])
    {
        int v = id[e[i].u] ^ id[e[i].v] ^ u;
        if (v == par) continue;
        add(v,u,val);
    }
}
void precalc(int u,int par)
{
    for (int v : node[u])
    {
        d[c[v]] = 0;
        d1[c[v]]++;
        q.push({d[c[v]],c[v]});
        q1.push({d1[c[v]],c[v]});
        idtr[v] = cnt;
    }
    avail[u] = false;
    sz[u] = node[u].size();bc[u] = -1;
    for (int i : adjcc[u])
    {
        int v = id[e[i].u] ^ id[e[i].v] ^ u;
        if (v == par) continue;
        precalc(v,u);
        sz[u] += sz[v];
        if (bc[u] == -1 || sz[bc[u]] < sz[v])
        {
            bc[u] = v;
            eid[u] = i;
        }
    }
}
void calc(int u,int par)
{
    avail[u] = false;
    for (int i : adjcc[u])
    {
        int v = id[e[i].u] ^ id[e[i].v] ^ u;
        if (v != par && v != bc[u])
        {
            calc(v,u);
            while (!q.empty() && q.top().first != d[q.top().second]) q.pop();
            while (!q1.empty() && q1.top().first != d1[q1.top().second]) q1.pop();
            e[i].res = q.top().first + q1.top().first;
            add(v,u,-1);
        }
    }
    if (bc[u] > 0)
    {
        calc(bc[u],u);
        while (!q.empty() && q.top().first != d[q.top().second]) q.pop();
        while (!q1.empty() && q1.top().first != d1[q1.top().second]) q1.pop();
        e[eid[u]].res = q.top().first + q1.top().first;
    }
    for (int i : adjcc[u])
    {
        int v = id[e[i].u] ^ id[e[i].v] ^ u;
        if (v != par && v != bc[u]) add(v,u,1);
    }
    for (int v : node[u]) addc(c[v],1);
}
void del(int u,int par)
{
    for (int v : node[u]) d[c[v]] = d1[c[v]] = 0;
    for (int i : adjcc[u])
    {
        int v = id[e[i].u] ^ id[e[i].v] ^ u;
        if (v != par) del(v,u);
    }
}
void solve()
{
    presolve();
    res = 0;
    cnt = 0;
    fill(avail + 1,avail + n + 1,true);
    for (int i = 1;i <= n;++i)
    {
        if (avail[id[i]])
        {
            while (!q.empty()) q.pop();
            while (!q1.empty()) q1.pop();
            ++cnt;
            precalc(i,-1);
            ans[cnt] = q1.top().first;
            res += ans[cnt];
            calc(id[i],-1);
            del(id[i],-1);
        }
    }
    for (int i = 1;i <= m;++i)
    {
        if (e[i].ch) cout << res - ans[idtr[e[i].v]] + e[i].res;
        else cout << res;
        if (i != m) cout << " ";
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
//    freopen("C.inp","r",stdin);
//    freopen("C.out","w",stdout);
    int t;
    cin >> t;
    while (t--)
    {
        input();
        solve();
        if (t != 0) cout << "\n";
    }
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 3ms
memory: 15944kb

input:

3
7 5
1 2 1 2 1 2 1
1 2
1 3
2 4
5 6
5 7
3 3
1 2 3
1 2
1 3
2 3
2 3
12345 54321
1 2
1 2
1 1

output:

6 5 5 5 4
1 1 1
1 1 1

result:

ok 3 lines

Test #2:

score: -100
Memory Limit Exceeded

input:

5557
2 7
79960 79960
2 2
1 1
1 1
2 2
1 1
2 1
1 2
9 8
21881 70740 70740 21881 22458 22458 639 21881 70740
3 3
1 6
5 8
7 5
5 7
2 3
5 1
7 6
6 7
13064 20716 6746 13064 6746 69225
5 5
4 1
4 1
1 6
4 5
3 2
3 2
8 4
45146 14400 45146 45146 14400 72969 14400 45146
8 6
1 3
4 6
8 3
18 13
48132 37949 92338 92338...

output:


result: