这道题在会prufer后会很简单,就是组合数嘛
避免高精度要分解质因数。
到分解质因数那一步我做的完全没问题。
高精度乘法死活查不出来错了。于是随便贴了一个高精度乘法。可算是过了
明天继续。
#include <cstdio>
#include <iostream>
#include <cstring>
#define N 1100
#define ll long long
using namespace std;
struct abcd{
ll xx[400];
int cnt;
abcd(int x=0)
{
memset(xx,0,sizeof xx);
xx[1]=x;
cnt=1;
}
ll& operator [] (int x)
{
return xx[x];
}
}ans(1);
bool flag[N];
int a[N], b[N], num[N], prime[N];
int n, m, left1, cnt, cnt1;
inline void init() {
cnt1 = 0;
memset(flag, true, sizeof(flag));
for(int i = 2; i < N; ++i) {
if(flag[i]) {
prime[++cnt1] = i;
for(int j = i + i; j < N; j+= i) flag[j] = false;
}
}
// for(int i = 1; i <= cnt1; ++i) printf("%d ", prime[i]);
// printf("\n\n");
return ;
}
//inline void multip(int k) {
//
// for(int i = 1; i < N-1; ++i) {
// ans[i] = ans[i] * k;
int j = i;
while(ans[j] >= 10) {
ans[j + 1]+= ans[j]/10;
ans[j]%= 10;
++j;
}
// }
// return ;
//}
ostream& operator << (ostream& os,abcd &x)
{
int i;
printf("%lld",x[x.cnt]);
for(i=x.cnt-1;i;i--)
printf("%08lld",x[i]);
return os;
}
abcd operator *= (abcd &x,abcd &y)
{
int i,j;
abcd z;
for(i=1;i<=x.cnt;i++)
for(j=1;j<=y.cnt;j++)
z[i+j-1]+=x[i]*y[j],z[i+j]+=z[i+j-1]/100000000,z[i+j-1]%=100000000;
z.cnt=x.cnt+y.cnt;
if(!z[z.cnt])
--z.cnt;
x=z;
}
void Quick_Power(int i,int y)
{
abcd x(i);
while(y)
{
if(y&1)ans*=x;
x*=x;
y>>=1;
}
}
int main() {
freopen("1005.in", "r", stdin);
scanf("%d", &n); m = cnt = 0; left1 = n - 2;
for(int i = 1; i <= n; ++i) {scanf("%d", a+i); if(a[i] == -1) ++m; else {left1-= a[i] - 1; b[++cnt] = a[i] - 1;}}
memset(num, 0, sizeof(num));
init();
for(int i = 1; i <= n - 2; ++i) {
int j = i; if(n - 2 == 0 || n - 2 == 1) continue;
for(int k = 1; k <= cnt1; ++k) {
while(j % prime[k] == 0) {
num[k]++;
j/= prime[k];
}if(j == 1) break;
}
}
b[++cnt] = left1;
for(int digit = 1; digit <= cnt; ++digit) {
int d = b[digit]; if(d == 0 || d == 1) continue;
for(int i = 1; i <= d; ++i) {
int j = i;
for(int k = 1; k <= cnt1; ++k) {
while(j % prime[k] == 0) {
num[k]--;
j/= prime[k];
}if(j == 1) break;
}
}
}
int i1 = m;
for(int j = 1; j <= cnt1; ++j) {
while(i1 % prime[j] == 0) {
num[j]+= left1;
i1/= prime[j];
}if(i1 == 1) break;
}
// for(int i = 1; i <= 6; ++i) printf("%d ", num[i]);
// for(int i = 1; i <= cnt1; ++i) {
// int d = prime[i], z = num[i];
// for(int j = 1; j <= z; ++j) multip(d);
// }
for(int i=1;i<=cnt1;i++)
if(num[i])
Quick_Power(prime[i],num[i]);
cout<<ans<<endl;
// int v;
// for(int i = N - 1; i >= 1; --i) if(ans[i] != 0) {v = i; break;}
// for(int i = v; i >= 1; --i) printf("%d", ans[i]);
return 0;
}