QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#376950 | #8055. Balance | PetroTarnavskyi | WA | 1ms | 5796kb | C++20 | 5.4kb | 2024-04-04 19:30:02 | 2024-04-04 19:30:03 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define RFOR(i, a, b) for(int i = (a) - 1; i >= (b); i--)
#define SZ(a) int(a.size())
#define ALL(a) a.begin(), a.end()
#define PB push_back
#define MP make_pair
#define F first
#define S second
typedef long long LL;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef double db;
const int N = 1 << 17;
const int M = 1 << 18;
int n, m;
int a[N];
vector<PII> g[N];// cleared
bool isBridge[M]; // cleared
bool used[N];// cleared
int tin[N], fup[N], timer;
int comp[N];// cleared
int cntComps;
int szComp[N];// cleared
VI g2[N];// cleared
int szSubtree[N];// cleared
int dpUp[N], dpDown[N];// cleared
PII edgeUp[N], edgeDown[N];// cleared
int cntA[N];// cleared
VI uniqueA;// cleared
int prefSum[N];// cleared
int lca;// cleared
PII edge1, edge2;// cleared
vector<PII> edgesUp, edgesDown;// cleared
int b[N];
void read()
{
cin >> n >> m;
FOR(i, 0, m)
{
int u, v;
cin >> u >> v;
u--;
v--;
g[u].PB({v, i});
g[v].PB({u, i});
}
FOR(i, 0, n)
cin >> a[i];
}
void dfs1(int v, int e)
{
used[v] = true;
tin[v] = fup[v] = timer++;
for (auto [to, i] : g[v])
{
if (i == e)
continue;
if (used[to])
{
fup[v] = min(fup[v], tin[to]);
}
else
{
dfs1(to, i);
fup[v] = min(fup[v], tin[to]);
if (fup[to] > tin[v])
{
isBridge[i] = true;
}
}
}
}
void dfs2(int v)
{
szComp[comp[v]]++;
for (auto [to, i] : g[v])
{
if (comp[to] == -1)
{
if (isBridge[i])
{
comp[to] = cntComps++;
g2[comp[v]].PB(comp[to]);
g2[comp[to]].PB(comp[v]);
}
else
{
comp[to] = comp[v];
}
dfs2(to);
}
}
}
void dfs3(int v, int p)
{
szSubtree[v] = szComp[v];
dpUp[v] = 0;
dpDown[v] = SZ(uniqueA);
for (int to : g2[v])
{
if (to == p)
continue;
dfs3(to, v);
int j = lower_bound(prefSum, prefSum + SZ(uniqueA) + 1, szSubtree[to]) - prefSum;
int tmpDpToUp = dpUp[to];
PII tmpedgeToUp = edgeUp[to];
if (j <= SZ(uniqueA) && prefSum[j] == szSubtree[to] && dpUp[to] == j - 1)
{
tmpDpToUp = j;
tmpedgeToUp = {v, to};
}
j = lower_bound(prefSum, prefSum + SZ(uniqueA) + 1, n - szSubtree[to]) - prefSum;
int tmpDpToDown = dpDown[to];
PII tmpedgeToDown = edgeDown[to];
if (j <= SZ(uniqueA) && prefSum[j] == n - szSubtree[to] && dpDown[to] == j + 1)
{
tmpDpToDown = j;
tmpedgeToDown= {v, to};
}
//cerr << v << " " << to << " " << dpUp[v] << " " << dpDown[to] << endl;
if (tmpDpToDown <= dpUp[v] + 1)
{
lca = v;
edge1 = edgeUp[v];
edge2 = tmpedgeToDown;
}
if (dpDown[v] <= tmpDpToUp + 1)
{
lca = v;
edge1 = tmpedgeToUp;
edge2 = edgeDown[v];
}
if (tmpDpToUp > dpUp[v])
{
dpUp[v] = tmpDpToUp;
edgeUp[v] = tmpedgeToUp;
}
if (tmpDpToDown < dpDown[v])
{
dpDown[v] = tmpDpToDown;
edgeDown[v] = tmpedgeToDown;
}
szSubtree[v] += szSubtree[to];
}
if (dpUp[v] == SZ(uniqueA) - 1)
{
lca = v;
edge1 = edgeUp[v];
edge2 = {-1, -1};
}
if (dpDown[v] == 1)
{
lca = v;
edge1 = {-1, -1};
edge2 = edgeDown[v];
}
}
void findEdgesUp(PII edge)
{
while (edge.F != -1)
{
auto [v, to] = edge;
edgesUp.PB(edge);
//cerr << "up " << to << " " << dpUp[to] << endl;
if (dpUp[to] == 0)
break;
edge = edgeUp[to];
}
}
void findEdgesDown(PII edge)
{
while (edge.F != -1)
{
auto [v, to] = edge;
edgesDown.PB(edge);
//cerr << "down " << to << " " << dpDown[to] << endl;
if (dpDown[to] == SZ(uniqueA))
break;
edge = edgeDown[to];
}
}
void dfs4(int v)
{
for (int to : g2[v])
{
if (b[to] == -1)
{
b[to] = b[v];
dfs4(to);
}
}
}
void solve()
{
fill(used, used + n, false);
fill(isBridge, isBridge + m, false);
timer = 0;
dfs1(0, -1);
/*FOR(v, 0, n)
{
for (auto [to, i] : g[v])
{
if (isBridge[i])
{
cerr << "bridge " << v << " " << to << endl;
}
}
}*/
fill(comp, comp + n, -1);
comp[0] = 0;
cntComps = 1;
fill(szComp, szComp + n, 0);
dfs2(0);
uniqueA = VI(a, a + n);
sort(ALL(uniqueA));
uniqueA.erase(unique(ALL(uniqueA)), uniqueA.end());
FOR(i, 0, n + 1)
cntA[i] = 0;
FOR(i, 0, n)
{
cntA[a[i]]++;
}
prefSum[0] = 0;
FOR(i, 0, SZ(uniqueA))
{
prefSum[i + 1] = prefSum[i] + cntA[uniqueA[i]];
}
lca = -1;
dfs3(0, -1);
if (lca == -1)
{
cout << "No\n";
return;
}
edgesUp.clear();
edgesDown.clear();
findEdgesUp(edge1);
findEdgesDown(edge2);
assert(SZ(edgesUp) + SZ(edgesDown) >= SZ(uniqueA) - 1);
reverse(ALL(edgesUp));
edgesUp.resize(SZ(uniqueA) - 1 - SZ(edgesDown));
FOR(i, 0, cntComps)
b[i] = -1;
reverse(ALL(uniqueA));
FOR(i, 0, SZ(edgesUp))
{
auto [u, v] = edgesUp[i];
b[u] = b[v] = uniqueA[i];
dfs4(v);
b[u] = -1;
}
FOR(i, 0, SZ(edgesDown))
{
auto [u, v] = edgesDown[i];
b[u] = b[v] = uniqueA[i + SZ(edgesUp)];
dfs4(u);
b[v] = -1;
}
FOR(i, 0, cntComps)
if (b[i] == -1)
{
b[i] = uniqueA.back();
}
cout << "Yes\n";
FOR(i, 0, n)
{
if (i)
cout << " ";
cout << b[comp[i]];
}
cout << "\n";
}
void clear()
{
FOR(i, 0, n)
{
g[i].clear();
g2[i].clear();
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int t;
cin >> t;
while (t--)
{
read();
solve();
clear();
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Wrong Answer
time: 1ms
memory: 5796kb
input:
5 5 4 1 2 2 3 3 4 4 5 1 2 3 4 5 5 4 1 2 1 3 1 4 1 5 1 2 3 4 5 5 4 1 2 1 3 1 4 1 5 1 2 2 2 3 5 6 1 2 1 2 2 3 3 4 4 5 3 5 1 2 1 2 1 2 2 1 2 1 2 1 2
output:
Yes 5 4 3 2 1 No Yes 2 1 2 2 3 Yes 2 2 2 1 1 No
result:
wrong answer 3-th smallest numbers are not same (test case 4)