QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#343183#4085. 통신망socpiteCompile Error//C++2015.5kb2024-03-02 01:45:452024-03-02 01:45:45

Judging History

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

  • [2024-03-02 01:45:45]
  • 评测
  • [2024-03-02 01:45:45]
  • 提交

answer

#include <bits/stdc++.h>
// #include "communication.h"
#define rb(x) ((x)&(-(x)))
#define fi first
#define se second
#define sz(V) ((int)(V).size())
using namespace std;
typedef pair<int, int> pii;

const int MAXN = 250055;
const int MAXM = 1000055;

int T[MAXN*4];
int Ts[MAXN*2], Tdeg[MAXN*2], _Ti[MAXN*2];

int GD[MAXM + MAXN*2];
int GDs[MAXN*2], GDdeg[MAXN*2], _GDi[MAXN*2];

int G[MAXM*2 + MAXN*2]; // save edges of graph in order of node
int Gs[MAXN*2]; // prefix sum of degree + i
int Gdeg[MAXN*2], _Gi[MAXN*2];
int RT[MAXN];

int cAlpha[MAXM];
int upperUp[MAXN*2], lowerUp[MAXN*2];
int upperAbove[MAXN*2], lowerAbove[MAXN*2];
int minOrderUp[MAXN*2], maxOrderUp[MAXN*2];
int minOrderAbove[MAXN*2], maxOrderAbove[MAXN*2];
int upCnt[MAXN*2], aboveCnt[MAXN*2];
int lcaUp[MAXN*2], lcaAbove[MAXN*2];

int dep[MAXN*2], prt[MAXN*2], prte[MAXN*2], dfo[MAXN*2], cnt[MAXN*2];
bitset<MAXM> treeEdge;

int A[MAXM], B[MAXM], C[MAXM];
bitset<MAXN*2> inV;

int Ans[MAXM];
int N, M, W, K, _N, _M;


int ud[MAXN*2];
int uf(int i) { return i == ud[i] ? i : (ud[i] = uf(ud[i])); }
void uf(int a, int b) { ud[uf(b)] = uf(a); }


namespace TE3 {
	void run() {
		for(int i = ::N, r; i; i--) if(3 <= ::dep[i]) {
			r = ::lowerUp[i];
			if(1 == ::dep[r] && ::inV[r])
				Ans[::C[::prte[i]]]++;
		}
	}
}


namespace TE2 {
	int fenwick[MAXN*2];

	pii IC[MAXN*2];
	int ICT[MAXN*2], ICs[MAXN*2];

	pii VIC[MAXN*4];
	int VICs[MAXN*2], VICdeg[MAXN*2], _VICi[MAXN*2];

	pii I[MAXN*6];
	int Is[MAXN*2];

	int dfoask[MAXN*4], dfoasks[MAXN*2], dfoaskdeg[MAXN*2], _dfoaski[MAXN*2];
	int dfopush[MAXN*2];
	int dfopop[MAXN*4], dfopops[MAXN*2], dfopopdeg[MAXN*2], _dfopopi[MAXN*2];

	void upd(int i, int r) {
		for(; i <= ::N; i += rb(i))
			fenwick[i] += r;
	}
	int get(int i) {
		int r = 0;
		for(; i; i -= rb(i))
			r += fenwick[i];
		return r;
	}

	void run() {
		// Sort IC + ICT by upperAbove dep
		for(int i = ::N; i; i--)
			if(4 <= ::dep[i] && ::inV[::prt[i]])
				ICs[::dep[::upperAbove[i]]]++;
		for(int i = 1; i < ::N; i++)
			ICs[i+1] += ICs[i];
		for(int i = ::N; i; i--) if(4 <= ::dep[i] && ::inV[::prt[i]]) {
			int &idx = ICs[::dep[::upperAbove[i]]];
			ICT[idx] = ::prt[i];
			IC[idx] = { ::dep[::upperAbove[i]], ::dep[::lowerAbove[i]] };
			idx--;
		}

		// Build VIC
		for(int i = 1; ICT[i]; i++) VICdeg[ICT[i]]++;
		for(int i = 1; i < ::N; i++) VICs[i+1] = VICs[i] + VICdeg[i] + 1;
		memcpy(_VICi, VICs, ::N+1 << 2);
		for(int i = 1; ICT[i]; i++) VIC[_VICi[ICT[i]]++] = IC[i];

		// Make I
		{
			pii *it = I+1;
			for(int i = 1, s, e; i <= ::N; i++) if(3 <= ::dep[i] && ::inV[i]) {
				Is[i] = int(it - I);
				s = 2; e = ::dep[i] - 1;
				for(pii *cit = VIC + VICs[i];; cit++) {
					if(!cit->fi || s > e) break;
					if(cit->se <= cit->fi) continue;
					if(s <= cit->fi) {
						*it++ = { s, min(cit->fi, e) };
						s = cit->se + 1;
					} else {
						if(s <= cit->se)
							s = cit->se + 1;
					}
				}
				if(s <= e) *it++ = {s, e};
				it++;
			}
		}

		// Sweeping
		for(int i = ::N; i; i--) {
			if(3 <= ::dep[i] && ::inV[i]) {
				dfopush[::dfo[i]] = i;
				dfopopdeg[::dfo[i] + ::cnt[i]]++;
			}
			if(2 <= ::dep[i])
				dfoaskdeg[::dfo[::lcaUp[i]]]++;
		}
		for(int i = 1; i <= ::N+1; i++) {
			dfoasks[i+1] = dfoasks[i] + dfoaskdeg[i] + 1;
			dfopops[i+1] = dfopops[i] + dfopopdeg[i] + 1;
		}
		memcpy(_dfoaski, dfoasks, ::N+2 << 2);
		memcpy(_dfopopi, dfopops, ::N+2 << 2);
		for(int i = 1; i <= ::N; i++) {
			if(3 <= ::dep[i] && ::inV[i]) dfopop[_dfopopi[::dfo[i] + ::cnt[i]]++] = i;
			if(2 <= ::dep[i]) dfoask[_dfoaski[::dfo[::lcaUp[i]]]++] = i;
		}
		for(int dfotime = 1; dfotime <= ::N; dfotime++) {
			if(dfopush[dfotime]) {
				for(pii *it = I + Is[dfopush[dfotime]]; it->fi; it++) {
					upd(it->fi, 1);
					upd(it->se + 1, -1);
				}
			}
			for(int *it = dfopop + dfopops[dfotime]; *it; it++) {
				for(pii *iit = I + Is[*it]; iit->fi; iit++) {
					upd(iit->fi, -1);
					upd(iit->se + 1, 1);
				}
			}
			for(int *askit = dfoask + dfoasks[dfotime]; *askit; askit++)
				::Ans[::C[::prte[*askit]]] += get(::dep[*askit]);
		}
	}
}


namespace TE1C2 {
	int fenwick[MAXN*2];

	pii OC[MAXN*2]; // { dep, c }
	int OCs[MAXN*2], OCn;

	pii OV[MAXN*2]; // { dep, v }
	int OVs[MAXN*2], OVn;

	inline void upd(int i, int r) {
		for(; i <= ::N; i += rb(i))
			fenwick[i] += r;
	}
	inline int get(int i) {
		int r = 0;
		for(; i; i -= rb(i))
			r += fenwick[i];
		return r;
	}
	inline int get(int s, int e) { return get(e) - get(s-1); }

	void run() {
		// Sort OC & OV by dep
		for(int i = ::N; i; i--) {
			if(3 <= ::dep[i] && inV[::prt[i]]) {
				OCs[::dep[i]]++;
				OCn++;
			}
			if(4 <= ::dep[i]) {
				OVs[::dep[::lowerUp[i]]]++;
				OVn++;
			}
		}
		for(int i = 1; i < ::N; i++) {
			OCs[i+1] += OCs[i];
			OVs[i+1] += OVs[i];
		}
		for(int i = ::N; i; i--) {
			if(3 <= ::dep[i] && inV[::prt[i]])
				OC[OCs[::dep[i]]--] = { ::dep[i], i };
			if(4 <= ::dep[i])
				OV[OVs[::dep[::lowerAbove[i]]]--] = { ::dep[::lowerAbove[i]], i };
		}

		for(pii *vit = OV+OVn, *cit = OC+OCn;; vit--) {
			if(!vit->fi) break;
			for(; vit->fi < cit->fi; cit--) {
				upd(::dfo[::lcaAbove[cit->se]], 1);
				upd(::dfo[cit->se], -1);
			}
			::Ans[::C[::prte[vit->se]]] += get(::dfo[vit->se], ::dfo[vit->se] + ::cnt[vit->se] - 1);
		}
	}
}


namespace TE1C1 {// when prte[v] is removed, if all back edges goes to u, then u becomes AC
	void run() {
		for(int v = ::N, u; v; v--) if(4 <= ::dep[v]) {
            cout << "SUS" << v << endl;
			if(::upperUp[v] != ::lowerUp[v]) continue;
			u = ::upperUp[v];
			if(1 < ::dep[u] && inV[u]) ::Ans[::C[::prte[v]]]++;
		}
	}
}


namespace BE {
	int AC[MAXN*2];

	void dfs(int i, int d) {
        // cout << ::aboveCnt[i] << endl;
		for(int *eit = ::G + ::Gs[i];; eit++) {
			if(!*eit) break;
			::Ans[::C[*eit]] = W + (AC[d] - AC[::dep[::A[*eit]] + 1]);
		}
		for(int *eit = ::T + ::Ts[i];; eit++) {
			if(!*eit) break;
			AC[d+1] = AC[d] + (::inV[i] && 1 == ::aboveCnt[::B[*eit]] ? 1 : 0);
			dfs(::B[*eit], d+1);
		}
	}

	void run() {
		for(int i = ::K; i; i--) dfs(::RT[i], 1);
	}
}

namespace DFS2 {
	int QU[MAXN*6], QUs[MAXN*2], QUdeg[MAXN*2], _QUi[MAXN*2];
	int QA[MAXN*6], QAs[MAXN*2], QAdeg[MAXN*2], _QAi[MAXN*2];

	bitset<MAXN*2> black;

	void dfs(int i) {
		for(int *eit = ::T + ::Ts[i], v;; eit++) {
			if(!*eit) break;
			v = ::B[*eit];
			dfs(v);
			::upCnt[i] += ::upCnt[v];
			::aboveCnt[i] += ::aboveCnt[v];
			::uf(i, v);
		}
		black[i] = true;
		for(int *eit = QU + QUs[i], e, v;; eit++) {
			e = *eit;
			if(!e) break;
			v = ::minOrderUp[e]^::maxOrderUp[e]^i;
			if(black[v]) ::lcaUp[e] = ::uf(v);
		}
		for(int *eit = QA + QAs[i], e, v;; eit++) {
			e = *eit;
			if(!e) break;
			v = ::minOrderAbove[e]^::maxOrderAbove[e]^i;
			if(black[v]) ::lcaAbove[e] = ::uf(v);
		}
	}

	void run() {
		// Precompute for upCnt & aboveCnt
		for(int i = ::M; i; i--) if(!::treeEdge[i]) {
			::upCnt[::A[i]]--;
			::upCnt[::B[i]]++;
			::aboveCnt[::cAlpha[i]]--;
			::aboveCnt[::B[i]]++;
		}

		// Build QU & QA
		for(int i = ::N; i; i--) {
			if(::minOrderUp[i]) {
				QUdeg[::minOrderUp[i]]++;
				QUdeg[::maxOrderUp[i]]++;
			}
			if(::minOrderAbove[i]) {
				QAdeg[::minOrderAbove[i]]++;
				QAdeg[::maxOrderAbove[i]]++;
			}
		}
		for(int i = 1; i <= ::N; i++) {
			QUs[i+1] = QUs[i] + QUdeg[i] + 1;
			QAs[i+1] = QAs[i] + QAdeg[i] + 1;
		}
		memcpy(_QUi, QUs, ::N+1 << 2);
		memcpy(_QAi, QAs, ::N+1 << 2);
		for(int i = 1; i <= ::N; i++) {
			if(::minOrderUp[i]) {
				QU[_QUi[::minOrderUp[i]]++] = i;
				QU[_QUi[::maxOrderUp[i]]++] = i;
			}
			if(::minOrderAbove[i]) {
				QA[_QAi[::minOrderAbove[i]]++] = i;
				QA[_QAi[::maxOrderAbove[i]]++] = i;
			}
		}

		// Run DFS
		iota(::ud, ::ud + ::N + 1, 0);
		for(int i = ::K; i; i--) dfs(::RT[i]);
	}
}


namespace MMO {
	// sorted by dfo
	int O[MAXN*2];

	int pdep[MAXN*2];

	inline void goup(int dp[], int i, int deplim) {
		int v = i;
		while(true) {
			v = ::uf(v);
			if(::dep[v] <= deplim) break;
			dp[v] = i;
			::uf(::prt[v], v);
		}
	}

	void run() {
		// Sort by dfo
		for(int i = ::N; i; i--) O[::dfo[i]] = i;

		// Precompute pdep
		for(int i = ::N, t; i; i--) {
			t = ::dep[i];
			for(int *eit = ::G + ::Gs[i], pd;; eit++) {
				if(!*eit) break;
				pd = ::dep[::A[*eit]];
				if(pd < t) t = pd;
			}
			pdep[i] = t;
		}

		// Compute minOrderUp
		iota(::ud, ::ud + ::N + 1, 0);
		for(int *it = O+1;; it++) {
			if(!*it) break;
			goup(::minOrderUp, *it, pdep[*it]);
		}

		// Compute maxOrderUp
		iota(::ud, ::ud + ::N + 1, 0);
		for(int *it = O+::N;; it--) {
			if(!*it) break;
			goup(::maxOrderUp, *it, pdep[*it]);
		}

		// Compute minOrderAbove
		iota(::ud, ::ud + ::N + 1, 0);
		for(int *it = O+1;; it++) {
			if(!*it) break;
			goup(::minOrderAbove, *it, pdep[*it] + 1);
		}

		// Compute maxOrderAbove
		iota(::ud, ::ud + ::N + 1, 0);
		for(int *it = O+::N;; it--) {
			if(!*it) break;
			goup(::maxOrderAbove, *it, pdep[*it] + 1);
		}
	}
}


namespace UL {
	// sorted by dep
	int O[MAXN*2], _I[MAXN*2];

	inline void goup(int dp[], int i, int depi) {
		for(int *eit = ::GD + ::GDs[i], v;; eit++) {
			if(!*eit) break;
			v = ::B[*eit];
			while(true) {
				v = ::uf(v);
				if(::dep[v] <= depi) break;
				dp[v] = i;
				::uf(::prt[v], v);
			}
		}
	}

	void run() {
		// Sort by dep
		for(int i = ::N; i; i--) _I[::dep[i]]++;
		for(int i = 2; i <= ::N; i++) _I[i] += _I[i-1];
		for(int i = ::N; i; i--) O[_I[::dep[i]]--] = i;

		// Compute upperUp
		iota(::ud, ::ud + ::N + 1, 0);
		for(int *it = O+1;; it++) {
			if(!*it) break;
			goup(::upperUp, *it, ::dep[*it]);
		}

		// Compute lowerUp
		iota(::ud, ::ud + ::N + 1, 0);
		for(int *it = O+::N;; it--) {
			if(!*it) break;
			goup(::lowerUp, *it, ::dep[*it]);
		}

		// Compute upperAbove
		iota(::ud, ::ud + ::N + 1, 0);
		for(int *it = O+1;; it++) {
			if(!*it) break;
			goup(::upperAbove, *it, ::dep[*it] + 1);
		}

		// Compute lowerAbove
		iota(::ud, ::ud + ::N + 1, 0);
		for(int *it = O+::N;; it--) {
			if(!*it) break;
			goup(::lowerAbove, *it, ::dep[*it] + 1);
		}
	}
}


namespace DFS1 {
	int path[MAXN*2];
	bitset<MAXN*2> chk;

	int dfstime;

	void dfs(int i, int pe) {
		chk[i] = true;
		path[::dep[i]] = i;
		::cnt[i] = 1;
		::dfo[i] = ++dfstime;
		for(int *it = ::G + ::Gs[i], e, v;; it++) {
			e = *it;
			if(!e) break;
			if(e == pe) continue;
			v = ::A[e]^::B[e]^i;
			if(chk[v]) {
				if(::dep[v] < ::dep[i])
					::cAlpha[e] = path[::dep[v]+1];
				continue;
			}
			::treeEdge[e] = true;
			::dep[v] = ::dep[i] + 1;
			::prt[v] = i;
			::prte[v] = e;
			dfs(v, e);
			::cnt[i] += ::cnt[v];
		}
	}

	void run() {
		for(int i = 1, rt; i <= ::K; i++) {
			rt = ::RT[i];
			dep[rt] = 1;
			dfs(rt, 0);
		}
	}
}


namespace BCC {
	int A[MAXM], B[MAXM], C[MAXM];
	int RT[MAXN], _I[MAXN], _OI[MAXN*2];
	int N, M, K;

	int st[MAXM], stn;

	int disc[MAXN], low[MAXN];
	bitset<MAXM> cutedge;
	bitset<MAXN> cutvertex;

	int dfstime, cutcnt;

	void dfs(int u, int pe) {
		disc[u] = low[u] = ++dfstime;
		int children = 0;
		bool cut = false;
		for(int *it = ::G + ::Gs[u], e, v;; it++) {
			e = *it;
			if(!e) break;
			if(e == pe) continue;
			v = ::A[e]^::B[e]^u;
			if(disc[v]) {
				if(disc[v] < low[u])
					low[u] = disc[v];
				if(disc[v] < disc[u])
					st[++stn] = e;
			} else {
				children++;
				st[++stn] = e;
				dfs(v, e);
				if(low[v] < low[u])
					low[u] = low[v];
				if(disc[u] < low[v])
					cutedge[e] = true;
				if((!pe && 1 < children)
					|| (pe && disc[u] <= low[v])) {
					cut = true;
					if(st[stn] == e) stn--;
					else {
						K++;
						const int startn = N;
						while(true) {
							int a = ::A[st[stn]];
							int b = ::B[st[stn]];
							if(_I[a] <= startn) {
								N++;
								_I[a] = N;
								_OI[N] = a;
							}
							if(_I[b] <= startn) {
								N++;
								_I[b] = N;
								_OI[N] = b;
							}
							M++;
							A[M] = _I[a];
							B[M] = _I[b];
							C[M] = st[stn];
							stn--;
							if(!stn || st[stn+1] == e) break;
						}
						RT[K] = _I[u];
					}
				}
			}
		}
		if(cut) {
			cutvertex[u] = true;
			cutcnt++;
		}
	}

	void run(int rt) {
		dfs(rt, 0);
		if(stn) {
			if(1 == stn) stn--;
			else {
				K++;
				const int startn = N;
				while(stn) {
					int a = ::A[st[stn]];
					int b = ::B[st[stn]];
					if(_I[a] <= startn) {
						N++;
						_I[a] = N;
						_OI[N] = a;
					}
					if(_I[b] <= startn) {
						N++;
						_I[b] = N;
						_OI[N] = b;
					}
					M++;
					A[M] = _I[a];
					B[M] = _I[b];
					C[M] = st[stn];
					stn--;
				}
				RT[K] = _I[rt];
			}
		}
	}
}

void solve() {
	// Small case; Ans[*] = 0
	if(2 == N) return;

	// Build given graph
	for(int i = M; i; i--) {
		Gdeg[A[i]]++;
		Gdeg[B[i]]++;
	}
	for(int i = 1; i <= N; i++)
		Gs[i+1] = Gs[i] + Gdeg[i] + 1;
	memcpy(_Gi, Gs, N+1 << 2);
	for(int i = 1; i <= M; i++) {
		G[_Gi[A[i]]++] = i;
		G[_Gi[B[i]]++] = i;
	}

	// Find BCC from 1
	BCC::run(1);

	// Case; 1 + (N-1)

	// Now, given graph is connected

	// Case; cut edge
	for(int i = 1; i <= M; i++) if(BCC::cutedge[i])
		Ans[i] = (BCC::cutvertex[A[i]] && BCC::cutvertex[B[i]]) ? N : N-1;
	
	// Rebuild graph
	_N = N; _M = M;
	N = BCC::N; M = BCC::M; K = BCC::K;
	W = BCC::cutvertex.count();
	for(int i = 1; i <= N; i++)
		inV[i] = !BCC::cutvertex[BCC::_OI[i]];
	memcpy(A, BCC::A, M+1 << 2);
	memcpy(B, BCC::B, M+1 << 2);
	memcpy(C, BCC::C, M+1 << 2);
	memcpy(RT, BCC::RT, K+1 << 2);
	memset(Gdeg, 0, N+1 << 2);
	for(int i = M; i; i--) {
		Gdeg[A[i]]++;
		Gdeg[B[i]]++;
	}
	for(int i = 1; i <= N; i++)
		Gs[i+1] = Gs[i] + Gdeg[i] + 1;
	memcpy(_Gi, Gs, N+1 << 2);
	memset(G, 0, M+M+N+1 << 2);
	for(int i = 1; i <= M; i++) {
		G[_Gi[A[i]]++] = i;
		G[_Gi[B[i]]++] = i;
	}

	// 1st DFS
	DFS1::run();

	// Edge depth consistency
	for(int i = M; i; i--)
		if(dep[A[i]] > dep[B[i]])
			swap(A[i], B[i]);
	
	// Build tree (forest, only down) & Rebuild graph (only back edge) (up / down)
	memset(Gdeg, 0, N+1 << 2);
	for(int i = M; i; i--) {
		if(treeEdge[i]) Tdeg[A[i]]++;
		else { Gdeg[B[i]]++; GDdeg[A[i]]++; }
	}
	for(int i = 1; i <= N; i++) {
		Ts[i+1] = Ts[i] + Tdeg[i] + 1;
		Gs[i+1] = Gs[i] + Gdeg[i] + 1;
		GDs[i+1] = GDs[i] + GDdeg[i] + 1;
	}
	memcpy(_Ti, Ts, N+1 << 2);
	memcpy(_Gi, Gs, N+1 << 2);
	memcpy(_GDi, GDs, N+1 << 2);
	memset(G, 0, M+N+1 << 2);
	for(int i = 1; i <= M; i++) {
		if(treeEdge[i]) T[_Ti[A[i]]++] = i;
		else {
			G[_Gi[B[i]]++] = i;
			GD[_GDi[A[i]]++] = i;
		}
	}

	// Compute upper/lower Up/Above
	UL::run();

	// Compute min/max Order Up/Above
	MMO::run();

	// 2nd DFS
	DFS2::run();

	// Answer; Back edge
	BE::run();

	// Answer; Tree edge 1 - Case 1
	TE1C1::run();

	// Answer; Tree edge 1 - Case 2
	TE1C2::run();

	// Answer; Tree edge 2
	TE2::run();

	// Answer; Tree edge 3
	TE3::run();

	// Answer; Tree edge - Base W
	for(int i = ::M; i; i--) if(treeEdge[i])
		Ans[C[i]] += W;

	M = _M;
}

vector<int> find_num_critical(int N, vector<pii> E) {
    ::N = N;
    ::M = sz(E);
    for(int i = 1; i <= ::M; i++)
        tie(::A[i], ::B[i]) = E[i-1];
    
    solve();
    
    return vector<int>(::Ans+1, ::Ans+::M+1);
}

int32_t main() {
	int N, M;
	vector<pii> E;
	cin >> N >> M;
	for (int i = 1; i <= M; ++i) {
		int u, v;
		cin >> u >> v;
		E.emplace_back(u, v);
	}
	auto ans = find_num_critical(N, E);
	for (auto val : ans) cout << val << "\n";
}

Details

/usr/bin/ld: /tmp/ccVsiZVL.o: in function `main':
answer.code:(.text.startup+0x0): multiple definition of `main'; /tmp/ccnYYSLK.o:implementer.cpp:(.text.startup+0x0): first defined here
collect2: error: ld returned 1 exit status