查看原帖
338147
01bit楼主2021/5/17 20:36
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#define ull unsigned long long
using namespace std;
ull max(ull a,ull b){
	return a>b?a:b;
}
struct Edge{
	int next;
	int v;
}edge[1000005];
int cnt=1,head[100005];
void addedge(int u,int v){
	edge[cnt].next=head[u];
	edge[cnt].v=v;
	head[u]=cnt++;
}
struct frac{
	ull cnt2=0,cnt3=0,cnt5=0;
	long double son=0;
	frac operator +(frac b){
		frac c;
		c.cnt2=max(cnt2,b.cnt2);
		c.cnt3=max(cnt3,b.cnt3);
		c.cnt5=max(cnt2,b.cnt5);
		c.son=0;
		long double t1=son*pow(2,c.cnt2-cnt2)*pow(3,c.cnt3-cnt3)*pow(5,c.cnt5-cnt5);
		long double t2=b.son*pow(2,c.cnt2-b.cnt2)*pow(3,c.cnt3-b.cnt3)*pow(5,c.cnt5-b.cnt5);
		t1+=t2;
		while(round(t1/2)*2==t1&&c.cnt2>0)--c.cnt2,t1/=2;
		while(round(t1/3)*3==t1&&c.cnt3>0)--c.cnt3,t1/=3;
		while(round(t1/5)*5==t1&&c.cnt5>0)--c.cnt5,t1/=5;
		c.son=t1;
		return c;
	}
};
frac w[100005];
int n,m;
int out[100005],in[100005];
void toposort(){
	queue<int>q;
	for(int i=1;i<=n;i++)if(in[i]==0){q.push(i);w[i].son=1;}
	while(!q.empty()){
		int front=q.front();
		q.pop();
		frac t=w[front];
		if(out[front]==0)continue;
		if(out[front]==2)t.cnt2++;
		if(out[front]==3)t.cnt3++;
		if(out[front]==4)t.cnt2+=2;
		if(out[front]==5)t.cnt5++;
		for(int i=head[front];i;i=edge[i].next){
			int x=edge[i].v;
			q.push(x);
			w[x]=w[x]+t;
		}
		w[front]=frac();
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%d",out+i);
		for(int j=1;j<=out[i];j++){
			int x;
			scanf("%d",&x);
			addedge(i,x);
			in[x]++;
		}
	}
	toposort();
	for(int i=1;i<=n;i++)
		if(out[i]==0){
			frac a=w[i];
			printf("%.0Lf %.0Lf\n",a.son,((long double)pow(2,a.cnt2)*pow(3,a.cnt3)*pow(5,a.cnt5)));
		}
	return 0;
}
2021/5/17 20:36
加载中...