QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#531926 | #6127. Kawa Exam | Mike_Vu | RE | 0ms | 0kb | C++14 | 6.2kb | 2024-08-24 23:10:36 | 2024-08-24 23:10:36 |
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double dou;
#define pii pair<int, int>
#define pb push_back
#define fi first
#define se second
bool maximize(ll &x, ll y ){
if (x < y) {x = y; return true;};
return false;
}
bool minimize(ll &x, ll y){
if (x > y) {x = y; return true;}
return false;
}
const int maxn = 1e5+5;
struct DSU{
vector<int> dsu, sz;
vector<int> val[maxn];
int n;
DSU(int _n = 0) {
n = _n;
dsu.assign(n+1, 0);
sz.assign(n+1, 1);
for (int i = 1; i <= n; i++) {
dsu[i] = i;
val[i].clear();
}
}
int f(int u) {
int tu = u;
while (u != dsu[u]) u = dsu[u];
dsu[tu] = u;
return u;
}
bool join(int u, int v){
u = f(u);
v = f(v);
if (u == v) return 0;
if (sz[u] < sz[v]) swap(u, v);
if (val[u].size() < val[v].size()) swap(val[u], val[v]);
for (int x : val[v]) {
val[u].pb(x);
}
val[v].clear();
dsu[v] = u;
sz[u] += sz[v];
return 1;
}
} dsu;
struct edge{
int u, v, ans = 0;
bool bridge;
edge(int i, int j) {
u = i;
v = j;
}
int op(int _u) {
return (_u == u ? v : u);
}
};
int n, m;
int c[maxn];
vector<int> a[maxn];
vector<edge> edges;
int num[maxn], low[maxn], timer;
int tin[maxn], tout[maxn], nodes[maxn], sz[maxn];
int cntcol[maxn], cntfre[maxn], ma, curans[maxn], sumo, tempans;
void input() {
cin >> n >> m;
edges.clear();
for (int i = 1; i <= n; i++) {
cin >> c[i];
a[i].clear();
num[i] = tin[i] = 0;
}
for (int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
edges.push_back(edge(u, v));
a[u].pb(i-1);
a[v].pb(i-1);
}
}
void tarjan(int u, int p = -1) {
num[u] = low[u] = ++timer;
for (int i : a[u]) {
if (i == p) continue;
int v = edges[i].op(u);
if (!num[v]) {
tarjan(v, i);
low[u] = min(low[u], low[v]);
}
else low[u] = min(low[u], num[v]);
}
if (low[u] == num[u] && p > -1) {
edges[p].bridge = 1;
}
}
void dfspre(int u, int p = -1) {
sz[u] = dsu.val[u].size();
tin[u] = ++timer;
nodes[timer] = u;
for (int i : a[u]) {
int v = edges[i].op(u);
if (v == p) continue;
dfspre(v, u);
sz[u] += sz[v];
}
tout[u] = timer;
}
void add(int u) {
for (int col : dsu.val[u]) {
cntfre[cntcol[col]]--;
cntcol[col]++;
cntfre[cntcol[col]]++;
ma = max(ma, cntcol[col]);
}
}
void sub(int u) {
for (int col : dsu.val[u]) {
--cntfre[cntcol[col]];
if (ma == cntcol[col] && cntfre[cntcol[col]] == 0) {
--ma;
}
cntcol[col]--;
cntfre[cntcol[col]]++;
}
}
void dfs1(int u, int p, bool keep) {
//find heavy
int heavy = -1, szheavy = 0;
for (int i : a[u]) {
int v = edges[i].op(u);
if (v == p) continue;
if (sz[v] > szheavy) {
szheavy = sz[v];
heavy = v;
}
}
//solve light
for (int i : a[u]) {
int v = edges[i].op(u);
if (v == p || v == heavy) continue;
dfs1(v, u, 0);
}
//solve heavy
if (heavy != -1) {
dfs1(heavy, u, 1);
}
//merge light
for (int i : a[u]) {
int v = edges[i].op(u);
if (v == p || v == heavy) continue;
for (int j = tin[v]; j <= tout[v]; j++) {
add(nodes[j]);
}
}
//merge u
add(u);
//answer
curans[u] = ma;
//keep
if (!keep) {
for (int j = tin[u]; j <= tout[u]; j++) {
sub(nodes[j]);
}
}
}
void dfs2(int u, int p, bool keep) {
//find heavy
int heavy = -1, szheavy = 0;
for (int i : a[u]) {
int v = edges[i].op(u);
if (i == p) continue;
if (sz[v] > szheavy) {
szheavy = sz[v];
heavy = i;
}
}
//solve light
for (int i : a[u]) {
int v = edges[i].op(u);
if (i == p || i == heavy) continue;
dfs2(v, i, 0);
}
//solve heavy
if (heavy != -1) {
dfs2(edges[heavy].op(u), heavy, 1);
}
//merge light
for (int i : a[u]) {
int v = edges[i].op(u);
if (i == p || i == heavy) continue;
for (int j = tin[v]; j <= tout[v]; j++) {
sub(nodes[j]);
}
}
//merge u
sub(u);
//answer
if (p != -1) {
edges[p].ans = curans[u]+ma-tempans;
}
//keep
if (!keep) {
for (int j = tin[u]; j <= tout[u]; j++) {
add(nodes[j]);
}
}
}
void solve() {
input();
dsu = DSU(n);
//tarjan
timer = 0;
for (int i = 1; i <= n; i++) {
if (!num[i]) tarjan(i);
dsu.val[i].pb(c[i]);
a[i].clear(); // construct new tree
}
//nen by dsu + new trees
for (int i = 0; i < m; i++) {
if (!edges[i].bridge) {
dsu.join(edges[i].u, edges[i].v);
}
else {
edges[i].u = dsu.f(edges[i].u);
edges[i].v = dsu.f(edges[i].v);
a[edges[i].u].pb(i);
a[edges[i].v].pb(i);
}
}
//solve by each tree
timer = ma = sumo = 0;
for (int i = 1; i <= n; i++) {
int u = dsu.f(i);
if (tin[u]) continue;
//precal
dfspre(u);
//dfs1 -> treeval
dfs1(u, -1, 1);
sumo += curans[u];
tempans = curans[u];
//dfs2 -> del + nodes
dfs2(u, -1, 1);
}
//sumo + valedge
cout << sumo+edges[0].ans;
for (int i = 1; i < m; i++) {
cout << ' ' << sumo+edges[i].ans;
}
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
int t;
cin >> t;
while (t--) {
solve();
cout << "\n";
}
}
/*
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
*/
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Runtime Error
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