bzoj1005: [HNOI2008]明明的烦恼

又是调了很久。。。自己测小数据不会WA啊。。。然后就拿标程对拍,拍着发现错了(输出000/0),然后继续拍。交还是WA。看一下数据生成,似乎有点不对劲。改一下。又拍出错了。原来我ans数组开小了。。。于是改后交上去就A了。。。又不爽又开心所以说数据范围要注意!输出格式错误要注意!。。。啊忘了说题解。。。会求Cn m就好啦(组合数。然后推一下公式(by 黄学长。然后高精乘低精再质因数暴力分解求阶乘就好了(黄学长的做法乘的时候有优化。。。(注意

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define rep(i,n) for(int i=1;i<=n;i++)
#define clr(x,c) memset(x,c,sizeof(x))
#define REP(i,s,t) for(int i=s;i<=t;i++)
int read(){
	int x=0;char c=getchar();bool f=true;
	while(!isdigit(c)){
		if(c=='-') f=false;c=getchar();
	}
	while(isdigit(c)) x=x*10+c-'0',c=getchar();
	return f?x:-x;
} 
const int nmax=1005;
const int inf=0x7f7f7f7f;
int a[nmax],prime[nmax],ans[6005],num[nmax],len,n,cnt=0,lft=0;
bool vis[nmax],flag=true;
void READ(){
	n=read();
	if(n==1){
		a[1]=read();
		if(!a[1]) printf("1");else printf("0");
		flag=false;
		return ;
	}
	rep(i,n) {
		a[i]=read();
		if(a[i]==-1) lft++;
		else if(!a[i]&&flag) printf("0"),flag=false;
		else cnt+=a[i]-1;
	}
	if(cnt>n-2&&flag) printf("0"),flag=false;
}
void init(){
	clr(vis,false);prime[0]=0;
	REP(i,2,1000) if(!vis[i]) {
		prime[++prime[0]]=i;
		for(int j=i+i;j<=1000;j+=i) vis[j]=true;
	}
}
void get(int x,int op){
	REP(i,2,x) {
	  int tmp=i;
	  rep(j,prime[0]) {
		if(tmp==1) break;
		while(tmp!=1&&tmp%prime[j]==0) num[j]+=op,tmp/=prime[j];
	  }
    }
}
void mul(int x){
	rep(i,len) ans[i]*=x;
    rep(i,len-1) if(ans[i]>=10) ans[i+1]+=ans[i]/10,ans[i]%=10;
    while(1){
    	if(ans[len]>=10) ans[++len]=ans[len-1]/10,ans[len-1]%=10;
    	else break;
    }
}
void work(){
	get(n-2,1);get(n-2-cnt,-1);
	rep(i,n) if(a[i]!=-1) get(a[i]-1,-1);
	clr(ans,0);ans[1]=1;len=1;
	rep(i,prime[0]) rep(j,num[i]) mul(prime[i]);
	rep(i,n-2-cnt) mul(lft);
	for(int i=len;i;i--) printf("%d",ans[i]);
}
int main(){
	READ();
	if(!flag) return 0;
	init();work();return 0;
};

  

1005: [HNOI2008]明明的烦恼

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 4077  Solved: 1623
[Submit][Status][Discuss]

Description

  自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在
任意两点间连线,可产生多少棵度数满足要求的树?

Input

  第一行为N(0 < N < = 1000),
接下来N行,第i+1行给出第i个节点的度数Di,如果对度数不要求,则输入-1

Output

  一个整数,表示不同的满足要求的树的个数,无解输出0

Sample Input

3
1
-1
-1

Sample Output

2

HINT

  两棵树分别为1-2-3;1-3-2

Source

 
[Submit][Status][Discuss]
原文地址:https://www.cnblogs.com/fighting-to-the-end/p/5683530.html