QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#20118#2214. Link Cut Digraphuezexh#WA 212ms24972kbC++172.1kb2022-02-14 20:09:312022-05-03 09:05:38

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-05-03 09:05:38]
  • 评测
  • 测评结果:WA
  • 用时:212ms
  • 内存:24972kb
  • [2022-02-14 20:09:31]
  • 提交

answer

#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
template<typename T> void cmin(T &a,const T &b){if(b<a)a=b;}
template<typename T> void cmax(T &a,const T &b){if(a<b)a=b;}

const int N=250005;

struct LnkNode{
	int v,nxt;
}edge[N];
int etot,fst[N];
void addedge_(int u,int v){
	++etot;
	edge[etot].v=v;
	edge[etot].nxt=fst[u];
	fst[u]=etot;
}
struct EdgeNode{
	int id,u,v;
}e[N],ne[N];
int dc,dfn[N],low[N],stk[N],tot,ins[N],sc,scc[N];
void dfs(int x){
	dfn[x]=low[x]=++dc;
	ins[stk[tot++]=x]=true;
	for(int i=fst[x];i;i=edge[i].nxt){
		int &y=edge[i].v;
		if(!dfn[y]){
			dfs(y);
			cmin(low[x],low[y]);
		}else if(ins[y]){
			cmin(low[x],dfn[y]);
		}
	}
	if(dfn[x]==low[x]){
		++sc;
		int y;
		do{
			ins[y=stk[--tot]]=false;
			scc[y]=sc;
		}while(y!=x);
	}
}

int n,m,u[N],v[N];
vector<int> g[N];

void Solve(int L,int R,int l,int r){
	if(L==R){
		for(int i=l;i<=r;++i)
			g[L].push_back(e[i].id);
		return;
	}
	int M=(L+R)>>1;
	etot=0,dc=0,sc=0;
	auto clr=[](int x){
		fst[x]=0,dfn[x]=0;
	};
	for(int i=l;i<=r;++i)
		if(e[i].id<=M)
			clr(e[i].u),clr(e[i].v);
	for(int i=l;i<=r;++i)
		if(e[i].id<=M)
			addedge_(e[i].u,e[i].v);
	for(int i=l;i<=r;++i){
		if(!dfn[e[i].u])
			dfs(e[i].u);
		if(!dfn[e[i].v])
			dfs(e[i].v);
	}
	int nen=0;
	for(int i=l;i<=r;++i)
		if(scc[e[i].u]==scc[e[i].v])
			ne[nen++]=e[i];
	int o=nen;
	for(int i=l;i<=r;++i)
		if(scc[e[i].u]!=scc[e[i].v])
			ne[nen++]={e[i].id,scc[e[i].u],scc[e[i].v]};
	copy_n(ne,nen,e+l);
	Solve(L,M,l,l+o-1);
	Solve(M+1,R,l+o,r);
}

int fu[N],siz[N];
ll ans;
int Find(int x){return fu[x]?fu[x]=Find(fu[x]):x;}
void Merge(int x,int y){
	x=Find(x),y=Find(y);
	if(x==y)
		return;
	ans+=(ll)siz[x]*siz[y];
	if(siz[x]<siz[y])
		swap(x,y);
	siz[x]+=siz[y];
	fu[y]=x;
}

int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;++i){
		scanf("%d%d",u+i,v+i);
		e[i]={i,u[i],v[i]};
	}
	Solve(1,m+1,1,m);
	fill_n(siz+1,n,1);
	for(int i=1;i<=m;++i){
		for(int id:g[i])
			Merge(u[id],v[id]);
		printf("%lld\n",ans);
	}
	return 0;
}

Details

Test #1:

score: 0
Wrong Answer
time: 212ms
memory: 24972kb