bzoj1211 [HNOI2004]树的计数

prufer序列及其推论。参考there

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
typedef long long ll;
int n, d[155], cnt[155];
ll ans=1;
vector<int> vec[3];
void calc(int p, int x){
	for(int i=2; i*i<=x; i++)
		if(x%i==0)
			while(x%i==0){
				x /= i;
				vec[p].push_back(i);
			}
	if(x>1)	vec[p].push_back(x);
}
int main(){
	cin>>n;
	int sum=0;
	for(int i=1; i<=n; i++){
		scanf("%d", &d[i]);
		sum += d[i] - 1;
		if((d[i]==0 && n!=1) || sum>n-2){
			printf("0\n");
			return 0;
		}
		for(int i=2; i<=d[i]-1; i++)
			calc(1, i);
	}
	if(n==1){
		printf("1\n");
		return 0;
	}
	if(sum!=n-2){
		printf("0\n");
		return 0;
	}
	for(int i=2; i<=n-2; i++)
		calc(2, i);
	sort(vec[1].begin(), vec[1].end());
	sort(vec[2].begin(), vec[2].end());
	vector<int>::iterator it=vec[1].begin();
	for(int i=0; i<vec[2].size(); i++){
		ans *= vec[2][i];
		while(it!=vec[1].end() && ans%(*it)==0){
			ans /= (*it);
			it++;
		}
	}
	cout<<ans<<endl;
	return 0;
}
posted @ 2018-04-10 16:50  poorpool  阅读(84)  评论(0编辑  收藏  举报