bzoj1005

来源:互联网 发布:python split 多个字符 编辑:程序博客网 时间:2024/06/05 18:40

这道题在会prufer后会很简单,就是组合数嘛

避免高精度要分解质因数。

到分解质因数那一步我做的完全没问题。

高精度乘法死活查不出来错了。于是随便贴了一个高精度乘法。可算是过了

明天继续。

#include <cstdio>#include <iostream>#include <cstring>#define N 1100#define ll long longusing 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;}