Mn Zn 求助 qwq
查看原帖
Mn Zn 求助 qwq
125355
Mihari楼主2021/2/24 19:25

90pts90pts,在 #5\tt \#5 的时候 WA\color{red}{\tt WA} 了,布吉岛为什么qwq,特来求助各位奆佬棒棒这个萌新

由于没有看题解,所以写得可能有点复杂,请各位见谅

#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
namespace Elaina{
    #define rep(i, l, r) for(int i=l, i##_end_=r; i<=i##_end_; ++i)
    #define fep(i, l, r) for(int i=l, i##_end_=r; i>=i##_end_; --i)
    #define fi first
    #define se second
    #define Endl putchar('\n')
    #define writc(x, c) fwrit(x), putchar(c)
    typedef long long ll;
    typedef pair<int, int> pii;
    typedef unsigned long long ull;
    typedef unsigned int uint;
    template<class T>inline T Max(const T x, const T y){return x<y? y: x;}
    template<class T>inline T Min(const T x, const T y){return x<y? x: y;}
    template<class T>inline T fab(const T x){return x<0? -x: x;}
    template<class T>inline void getMax(T& x, const T y){x=Max(x, y);}
    template<class T>inline void getMin(T& x, const T y){x=Min(x, y);}
    template<class T>T gcd(const T x, const T y){return y? gcd(y, x%y): x;}
    template<class T>inline T readin(T x){
        x=0; int f=0; char c;
        while((c=getchar())<'0' || '9'<c) if(c=='-') f=1;
        for(x=(c^48); '0'<=(c=getchar()) && c<='9'; x=(x<<1)+(x<<3)+(c^48));
        return f? -x: x;
    }
    template<class T>void fwrit(const T x){
        if(x<0) return putchar('-'), fwrit(-x);
        if(x>9) fwrit(x/10); putchar(x%10^48);
    }
}
using namespace Elaina;

const int maxn=65534+1;
const int logmaxn=16;
const int maxm=1e6*2;

struct edge{
	int to, nxt;
	edge(){}
	edge(const int T, const int N): to(T), nxt(N){}
}e[maxm+5];
int tail[maxn+5], ecnt;
inline void add_edge(const int u, const int v){
	e[ecnt]=edge(v, tail[u]); tail[u]=ecnt++;
}

int n;
// in-degree
int deg[maxn+5];

inline void input(){
	n=readin(1);
	memset(tail, -1, sizeof tail);
	int a;
	for(int i=1; i<=n; ++i){
		while((a=readin(1))){
			add_edge(a, i); // build the reverse edge
			++deg[i];
		}
	}
}

namespace dominant_tre{
	vector<int>G[maxn+5];
	int tp[maxn+5][logmaxn+5]; // the transfer array
	int dep[maxn+5]; // the depth of each node
	int rt; // the root of the dominant tree
	// initialization
	inline void initial(){
		// do not use 0 as the root, because empty and root is the same in the array tp[][]
		rt=n+1; dep[rt]=1;
	}
	// add a pair of relationship into dominant tree
	inline void add_rela(const int u, const int par){
		G[par].push_back(u);
		dep[u]=dep[par]+1, tp[u][0]=par;
		for(int j=1; j<=logmaxn; ++j)
			tp[u][j]=tp[tp[u][j-1]][j-1];
	}
	// get the lca of two points on the tree
	inline int findlca(int u, int v){
		if(dep[u]<dep[v]) swap(u, v);
		for(int j=logmaxn; j>=0; --j) if(dep[tp[u][j]]>=dep[v])
			u=tp[u][j];
		if(u==v) return u;
		for(int j=logmaxn; j>=0; --j) if(tp[u][j]!=tp[v][j])
			u=tp[u][j], v=tp[v][j];
		return tp[u][0];
	}
	int siz[maxn+5];
	void dfs(const int u, const int par){
		siz[u]=1;
		for(int i=0, sz=G[u].size(); i<sz; ++i){
			dfs(G[u][i], u);
			siz[u]+=siz[G[u][i]];
		}
	}
}
queue<int>Q;
int lca[maxn+5];
inline void topo(){
	dominant_tre::initial();
	for(int i=1; i<=n; ++i) if(!deg[i])
		lca[i]=dominant_tre::rt, Q.push(i);
	while(!Q.empty()){
		int u=Q.front(); Q.pop();
		dominant_tre::add_rela(u, lca[u]);
		for(int i=tail[u], v; ~i; i=e[i].nxt){
			v=e[i].to;
			if(!lca[v]) lca[v]=u;
			else lca[v]=dominant_tre::findlca(lca[v], u);
			if(!--deg[v]) Q.push(v);
		}
	}
}

signed main(){
	input();
	topo();
	dominant_tre::dfs(dominant_tre::rt, 0);
	for(int i=1; i<=n; ++i)
		printf("%d\n", dominant_tre::siz[i]-1); // except itself
	return 0;
}
2021/2/24 19:25
加载中...