AC日记——明明的烦恼 bzoj 1005

1005

 

思路:

  prufer编码+组合数;

 

代码:

#include <bits/stdc++.h>
using namespace std;
#define maxn 1005
#define maxlen 4000500
struct int666 {
    int len;
    char ai[maxlen];
    void mul(int pos)
    {
        long long cnt=0;
        for(int i=0;i<len;i++)
        {
            cnt+=pos*(ai[i]);
            ai[i]=cnt%10,cnt/=10;
        }
        while(cnt)
        {
            ai[len]=cnt%10;
            cnt/=10,len++;
        }
        while(len>1&&!ai[len-1]) len--;
    }
    void print()
    {
        for(int i=len-1;i>=0;i--) putchar(ai[i]+'0');
        putchar('\n');
    }
};
struct int666 ans;
int n,tot,ai[maxn],m,pi[maxn*10],num,bi[maxn*10];
bool if_p[maxn*10];
inline void in(int &now)
{
    int if_z=1;now=0;
    char Cget=getchar();
    while(Cget>'9'||Cget<'0')
    {
        if(Cget=='-')if_z=-1;
        Cget=getchar();
    }
    while(Cget>='0'&&Cget<='9')
    {
        now=now*10+Cget-'0';
        Cget=getchar();
    }
    now*=if_z;
}
void euler(int lit)
{
    for(int i=2;i<=lit;i++)
    {
        if(!if_p[i]) pi[++num]=i;
        for(int v=1;pi[v]*i<=lit&&v<=num;v++)
        {
            if_p[i*pi[v]]=true;
            if(i%pi[v]==0) break;
        }
    }
}
void apart(int now,int di)
{
    int temp=now;
    for(int v=1;v<=num;v++)
    {
        now=temp;
        while(now)
        {
            bi[v]+=di*now/pi[v];
            now/=pi[v];
        }
    }
}
int main()
{
//    freopen("bzoj_1005.in","r",stdin);
//    freopen("bzoj_1005.out","w",stdout);
    ans.len=1,ans.ai[0]=1;
    in(n),euler(maxn-1);
    if(n==1)
    {
        int pos;
        in(pos);
        if(pos<=0) printf("1");
        else printf("0");
        return 0;
    }
    for(int i=1;i<=n;i++)
    {
        in(ai[i]);
        if(!ai[i])
        {
            printf("0");
            return 0;
        }
        if(ai[i]==-1) m++;
        else tot+=--ai[i];
    }
    if(tot>n-2)
    {
        puts("0");
        return 0;
    }
    apart(n-2,1),apart(n-2-tot,-1);
    for(int i=1;i<=n;i++) if(ai[i]) apart(ai[i],-1);
    for(int i=1;i<=num;i++)
    {
        for(int v=1;v<=bi[i];v++) ans.mul(pi[i]);
    }
    for(int i=1;i<=n-2-tot;i++) ans.mul(m);
    ans.print();
    return 0;
}

 

posted @ 2017-06-09 20:00  IIIIIIIIIU  阅读(201)  评论(0编辑  收藏  举报