Magic

  利用Prufer序列,我们考虑序列中每个点是第几个插进去的,再考虑环的连接方式,我们有$$ans=\sum_{K=3}^n N^{N-K-1}*K*\frac{(K-1)!}{2} * \binom{N}{K}$$

  然而直接高精算会爆……

  注意到每一项与前一项相差不大,有$now=last*N/(N-K+1)$,所以我们算出来第一项以后不用每次重算后面的了……

 1 //Round7 A
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<iostream>
 6 #include<algorithm>
 7 #define rep(i,n) for(int i=0;i<n;++i)
 8 #define F(i,j,n) for(int i=j;i<=n;++i)
 9 #define D(i,j,n) for(int i=j;i>=n;--i)
10 #define pb push_back
11 using namespace std;
12 typedef long long LL;
13 const int N=100010;
14 /*******************template********************/
15 
16 int n;
17 struct bint{
18     LL v[1500];
19     int l;
20     LL& operator [] (int x){return v[x];}
21     bint(){l=0; memset(v,0,sizeof v);}
22 }ans;
23 const LL Limit=100000000000000LL;
24 void print(bint& a){
25     printf("%lld",a[a.l]);
26     D(i,a.l-1,1) printf("%014lld",a[i]);
27     puts("");
28 }
29 void mul(bint& a,const int &b){
30     LL tmp=0;
31     F(i,1,a.l){
32         a[i]=a[i]*b+tmp;
33         tmp=a[i]/Limit;
34         a[i]%=Limit;
35     }
36     if (tmp) a[++a.l]=tmp;
37 }
38 void del(bint& a,const int &b){
39     LL tmp=0,last=0;
40     D(i,a.l,1){
41         tmp=(a[i]+last*Limit)%b;
42         a[i]=(a[i]+last*Limit)/b;
43         last=tmp;
44     }
45     while(a[a.l]==0 && a.l) a.l--;
46 }
47 bint operator + (bint a,bint b){
48     int l=max(a.l,b.l);
49     F(i,1,l){
50         a[i]+=b[i];
51         if (a[i]>=Limit) a[i]-=Limit,a[i+1]++;
52     }
53     if (a[l+1]>0) a.l=l+1; else a.l=l;
54     return a;
55 }
56 int main(){
57 #ifndef ONLINE_JUDGE
58     freopen("A.in","r",stdin);
59     freopen("A.out","w",stdout);
60 #endif
61     scanf("%d",&n);
62     bint p,ans;
63     p[p.l=1]=1;
64     F(i,1,n-2) mul(p,n);
65     mul(p,n-1);
66     del(p,2);
67     F(k,3,n){
68         mul(p,n-k+1);
69         del(p,n);
70         ans=ans+p;
71 //        ans+=Pow(n,n-k-1)*k*fac[k-1]/2*C(n,k);
72     }
73     print(ans);
74     return 0;
75 }
View Code

相关文章: