1. 程式人生 > >[luogu2624 HNOI2008]明明的煩惱 (prufer+高精)

[luogu2624 HNOI2008]明明的煩惱 (prufer+高精)

i++ \n pac code ++ int memset spa log

傳送門

Solution

根據prufer序列做的題,具體可以看這裏
還知道了一種避免高精除的方法quq

Code

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define F(i,a,b) for(register int i=(a);i<=(b);i++)
#define R(i,a,b) for(register int i=(b);i>=(a);i--)
using namespace std;

inline int read() {
    int x=0,f=1;char c=getchar();
    while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
    while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
    return x*f;
}

const int N=1010,D=10000;

struct Bign{
    int da[N<<2],wei;
    Bign() {clear();}
    void out() {
        printf("%d",da[wei]);
        R(i,1,wei-1) printf("%04d",da[i]);
        putchar('\n');
    }
    void clear() {memset(da,0,sizeof(da));wei=0;}
}ans;
Bign operator*(Bign a,int b) {
    Bign res; res.wei=a.wei; int &wei=res.wei;
    F(i,1,wei) res.da[i]=a.da[i]*b;
    F(i,1,wei) res.da[i+1]+=res.da[i]/D,res.da[i]%=D;
    while(res.da[wei+1]) wei++,res.da[wei+1]=res.da[wei]/D,res.da[wei]%=D;
    return res;
}

int n,sum,cnt;
int a[N],p1[N],p2[N];

void get_p(int *p,int x) {
    int sqr=sqrt(x);
    F(i,2,sqr) while(x%i==0) x/=i,p[i]++;
    if(x>1) p[x]++;
}

int main() {
    n=read();
    F(i,1,n) {
        a[i]=read();if(a[i]==-1) continue;
        cnt++;sum+=a[i]-1;
        F(j,1,a[i]-1) get_p(p2,j);
    }
    if(sum>n-2) return putchar('0'),0;
    F(i,1,n-2) get_p(p1,i); 
    F(i,1,n-2-sum) get_p(p2,i),get_p(p1,n-cnt);
    F(i,1,n) p1[i]-=p2[i];
    ans.da[1]=1;ans.wei=1;
    F(i,1,n) F(j,1,p1[i]) ans=ans*i;
    ans.out();
    return 0;
}

[luogu2624 HNOI2008]明明的煩惱 (prufer+高精)