BZOJ1005: [HNOI2008]明明的烦恼
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1005
树的prufer编码是唯一的,然后推一发公式。(敲少一个字符调半天。。。
#include<cstring> #include<cstdio> #include<algorithm> #include<iostream> #define rep(i,l,r) for (int i=l;i<=r;i++) #define down(i,l,r) for (int i=l;i>=r;i--) #define clr(x,y) memset(x,y,sizeof(x)) #define maxn 100500 using namespace std; int ans[1005000]; int pri[maxn],vis[maxn],num[maxn],d[maxn],x[maxn]; int tot,cnt,n,sum,gg,l; int read(){ int x=0,f=1; char ch=getchar(); while (!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while (isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();} return x*f; } void pre(){ rep(i,2,1000){ if (!vis[i]) vis[i]=1,pri[++tot]=i; rep(j,1,tot) { vis[i*pri[j]]=1; if (i*pri[j]>1000) break; if (i%pri[j]==0) break; } } } void get(int x,int v){ int now=1; while (x!=1){ while (x%pri[now]==0) num[now]+=v,x/=pri[now]; now++; } } int main(){ pre(); n=read(); int len=n-2; rep(i,1,n){ d[i]=read(); if (d[i]!=-1) cnt++,sum+=d[i]-1; if (d[i]==0||len-(d[i]-1)<0) {gg=1; break;} if (d[i]!=-1) len-=d[i]-1; } if (gg) {puts("0"); return 0;} clr(num,0); rep(i,1,n-2) get(i,1); rep(i,1,n-2-sum) get(i,-1); rep(i,1,n){ if (d[i]!=-1) rep(j,1,d[i]-1) get(j,-1); } get(n-cnt,n-2-sum); l=1; x[1]=1; rep(i,1,tot){ while (num[i]){ num[i]--; rep(j,1,l) x[j]=x[j]*pri[i]; rep(j,1,l) x[j+1]+=x[j]/10,x[j]=x[j]%10; while (x[l+1]>0) {l++; x[l+1]+=x[l]/10; x[l]%=10; } } } while (x[l]==0) l--; down(i,l,1) printf("%d",x[i]); return 0; }