脑残题目打了半天打不出来
这高精打的我要吐血(其实是ctrlC+V的)
我决定不A这题了
但是思路还是讲讲
这题还是肥肠显然的prufer数列的应用嘛
我的prufer数列一共有n-2个元素嘛(n为节点个数)
那么我已经确定的有sigma(dushu[i]-1)个嘛
那么一共的方案数就有C(n-2,sigma(dushu[i]-1))嘛
但是还有重复的情况嘛
那么就除掉tot!/(d(s)-1)嘛
然后还有剩下的一些空嘛
这些空可以被所有度数为-1的节点填上嘛
那么就是快速幂k^(n-2-tot)嘛
下面是我WA的代码
有兴趣的可以帮我找找错误
#include<iostream>
#include<fstream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
const int MAXN = 4100;
int n;
int d[10003];
int k;
int p[2][1003];
void cal(int x,int k){
for(int i=2;;i++){
while(x%i==0){
p[k][i]++,x/=i;
}
if(x==1){
break;
}
}
}
struct bign{
int len,s[MAXN];
bign (){
memset(s,0,sizeof(s));
len=1;
}
bign (int num) { *this = num; }
bign (const char *num) { *this = num; }
bign operator = (const int num){
char s[MAXN];
sprintf(s, "%d", num);
*this = s;
return *this;
}
bign operator = (const char *num){
for(int i = 0; num[i] == '0'; num++) ; //去前导0
len = strlen(num);
for(int i = 0; i < len; i++) s[i] = num[len-i-1] - '0';
return *this;
}
bign operator + (const bign &b) const{
bign c; //+
c.len = 0;
for(int i = 0, g = 0; g || i < max(len, b.len); i++){
int x = g;
if(i < len) x += s[i];
if(i < b.len) x += b.s[i];
c.s[c.len++] = x % 10;
g = x / 10;
}
return c;
}
bign operator += (const bign &b){
*this = *this + b;
return *this;
}
void clean(){
while(len > 1 && !s[len-1]) len--;
}
bign operator * (const bign &b) {
bign c; //*
c.len = len + b.len;
for(int i = 0; i < len; i++){
for(int j = 0; j < b.len; j++){
c.s[i+j] += s[i] * b.s[j];
}
}
for(int i = 0; i < c.len; i++){
c.s[i+1] += c.s[i]/10;
c.s[i] %= 10;
}
c.clean();
return c;
}
bign operator *= (const bign &b){
*this = *this * b;
return *this;
}
bign operator - (const bign &b){
bign c;
c.len = 0;
for(int i = 0, g = 0; i < len; i++){
int x = s[i] - g;
if(i < b.len) x -= b.s[i];
if(x >= 0) g = 0;
else{
g = 1;
x += 10;
}
c.s[c.len++] = x;
}
c.clean();
return c;
}
bign operator -= (const bign &b){
*this = *this - b;
return *this;
}
bign operator /(const bign &b){
bign c,f=0;
for(int i=len-1;i >= 0; i--){
f = f*10;
f.s[0] = s[i];
while(f >= b){
f -= b;
c.s[i]++;
}
}
c.len = len;
c.clean();
return c;
}
bign operator /=(const bign &b){
*this=*this/b;
return *this;
}
bign operator %(const bign &b){
bign r=*this/b;
r=*this-r*b;
return r;
}
bign operator %=(const bign &b){
*this=*this%b;
return *this;
}
bool operator <(const bign &b){
if(len!=b.len) return len<b.len;
for(int i=len-1;i>=0;i--){
if(s[i]!=b.s[i]) return s[i]<b.s[i];
}
return false;
}
bool operator > (const bign &b){
if(len!=b.len) return len>b.len;
for(int i=len-1;i>=0;i--){
if(s[i]!=b.s[i]) return s[i]>b.s[i];
}
return false;
}
bool operator ==(const bign &b){
return !(*this>b)&&!(*this<b);
}
bool operator != (const bign &b){
return !(*this == b);
}
bool operator <= (const bign &b){
return *this < b || *this == b;
}
bool operator >= (const bign &b){
return *this > b || *this == b;
}
string str() const{
string res="";
for(int i=0; i < len; i++) res = char(s[i]+'0') + res;
return res;
}
}ans;
istream& operator >>(istream &in, bign &x){
string s;
in>>s;
x=s.c_str();
return in;
}
ostream& operator <<(ostream &out, const bign &x){
out<<x.str();
return out;
}
bign qpow(bign x,int y){
if(y==1){
return x;
}else{
bign fanhui=qpow(x,y/2);
fanhui=fanhui*fanhui;
if(y%2==1){
fanhui*=x;
}
return fanhui;
}
}
int main(){
cin>>n;
int tot=0;
ans=1;
for(int i=1;i<=n;i++){
cin>>d[i];
if(d[i]==-1){
k++;
continue;
}
tot+=(d[i]-1);
}
for(int i=2;i<=tot;i++){
cal(i,0);
cal(i,0);
}
for(int i=1;i<=n;i++){
for(int j=2;j<d[i];j++){
cal(i,1);
}
}
bign x=k;
for(int i=2;i<=n-2;i++){
cal(i,1);
}
for(int i=2;i<=tot-n+2;i++){
cal(i,1);
}
for(int i=2;i<=1000;i++){
if(p[0][i]>p[1][i]){
ans*=qpow(i,p[0][i]-p[1][i]);
}
if(p[1][i]>p[0][i]){
ans/=qpow(i,p[1][i]-p[0][i]);
}
}
ans*=qpow(x,n-2-tot);
cout<<ans<<endl;
return 0;
}