蚂 蜂 良 好 , WA on#4#5#6求调,悬三关
查看原帖
蚂 蜂 良 好 , WA on#4#5#6求调,悬三关
342185
__builtin_orz楼主2024/9/6 11:54
#include<algorithm>
#include<cctype>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<queue>
#include<functional>
#ifdef _WIN32
#define getchar _getchar_nolock
#define putchar _putchar_nolock
#else
#define getchar getchar_unlocked
#define puhchar putchar_unlocked
#endif
#define _N_ 1000005
#define _M_ 10000006
#define MAYBE(ptr,attr)(ptr?ptr->attr:decltype(ptr->attr){})
#define int __uint128_t
int read(){
	int x=0,ch;
	while(!isdigit(ch=getchar()));
	do x=x*10+ch-'0';while(isdigit(ch=getchar()));
	return x;
}
void write(int x,int step=' '){
	static int o[505];
	int tp=0;
	while(x>9)o[++tp]=x%10+'0',x/=10;
	putchar(x+'0');
	while(tp)putchar(o[tp--]);
	putchar(step);
}
void new_line(){putchar('\n');}
struct Treap{
	Treap *ch[2];
	int val,rnk;
	Treap(int v){
		val=v;
		rnk=rand();
		ch[0]=ch[1]=nullptr;
	}
}*DAG_to[_N_];
void Treap_rotate(Treap *&now,int c){
	Treap *tmp=now->ch[c];
	now->ch[c]=tmp->ch[!c];
	tmp->ch[!c]=now;
	now=tmp;
}
void Treap_insert(Treap *&now,int x){
	if(!now)now=new Treap(x);
	else if(x<now->val){
		Treap_insert(now->ch[0],x);
		if(now->ch[0]->rnk<now->rnk)
			Treap_rotate(now,0);
	}else if(x>now->val){
		Treap_insert(now->ch[1],x);
		if(now->ch[1]->rnk<now->rnk)
			Treap_rotate(now,1);
	}
}
void Treap_each(Treap *now,std::function<void(int)>f){
	if(now){
		f(now->val);
		Treap_each(now->ch[0],f);
		Treap_each(now->ch[1],f);
	}
}
struct CFS{
	int val;
	CFS *nxt;
	CFS(int val,CFS *nxt=nullptr):val(val),nxt(nxt){}
}*G_to[_N_];
void CFS_add_edge(CFS *&head,int val){head=new CFS(val,head);}
void CFS_each(CFS *head,std::function<void(int)>f){
	for(CFS *i=head;i;i=i->nxt)
		f(i->val);
}
#define EACH(type,name,...)type##_each(name,[&](__VA_ARGS__){
#define END });
int SCC_low[_N_],SCC_dfn[_N_],SCC_dfn_cnt;
int SCC_stk[_N_],SCC_top;
int SCC_scc[_N_],SCC_scc_cnt;
int SCC_scc_siz[_N_];
void tarjan(int now){
	now[SCC_low]=now[SCC_dfn]=++SCC_dfn_cnt;
	SCC_stk[++SCC_top]=now;
	EACH(CFS,G_to[now],int to)
		if(!to[SCC_dfn]){
			tarjan(to);
			now[SCC_low]=std::min(now[SCC_low],to[SCC_low]);
		}else if(!to[SCC_scc])
			now[SCC_low]=std::min(now[SCC_low],to[SCC_dfn]);
	END
	if(now[SCC_dfn]==now[SCC_low]){
		SCC_scc_cnt++;
		int tmp;
		do{
			tmp=SCC_stk[SCC_top];
			tmp[SCC_scc]=SCC_scc_cnt;
			SCC_scc_cnt[SCC_scc_siz]++;
			SCC_top--;
		}while(tmp!=now);
	}
}
int ans[_N_],kind[_N_];
void topo(int now){
	now[ans]=now[SCC_scc_siz];
	now[kind]=1;
	int delta=0;
	EACH(Treap,now[DAG_to],int to)
		if(!to[ans])
			topo(to);
		if(to[ans]>delta){
			delta=to[ans];
			now[kind]=0;
		}
		if(to[ans]==delta)
			now[kind]++;
	END
	now[ans]+=delta;
}
signed main(){
	srand(time(nullptr));
	int n=read(),m=read(),MOD=read();
	for(int i=1;i<=m;i++){
		int f=read(),t=read();
		CFS_add_edge(G_to[f],t);
	}
	for(int i=1;i<=n;i++)
		if(!SCC_scc[i])
			tarjan(i);
	for(int i=1;i<=n;i++)
		EACH(CFS,G_to[i],int to)
			if(i[SCC_scc]!=to[SCC_scc])
				Treap_insert(i[SCC_scc][DAG_to],to[SCC_scc]);
		END
	int real_ans=0,real_kind=0;;
	for(int i=1;i<=SCC_scc_cnt;i++){
		if(!i[ans])
			topo(i);
		if(i[ans]>real_ans){
			real_ans=i[ans];
			real_kind=0;
		}
		if(i[ans]==real_ans)
			real_kind=(real_kind+i[kind])%MOD;
	}
	write(real_ans,'\n');
	write(real_kind);
	return 0;
}
2024/9/6 11:54
加载中...