【BZOJ 1005】[HNOI2008]明明的烦恼(化简的另一种方法)

来源:互联网 发布:我想开淘宝网店怎么开 编辑:程序博客网 时间:2024/05/18 03:57

【题目链接】:http://www.lydsy.com/JudgeOnline/problem.php?id=1005

【题意】

【题解】

题目和题解在上一篇;
这里 对
【(m^(n-2-tot))* (n-2)!】/【(n-2-tot)!* (d[1]-1)!*(d[2]-1)!……(d[n]-1)!】;
这个式子的化简再说一个方法;
对于n!
最后分解成质因子的时候;
质因子p的指数应该为
∑(n/i);
这里i为p,p^2,p^3….p^x,且p^x<=n
这样;
因为最大要求的阶乘为(n-2)!
所以先处理出2..n-2之间哪些数是质数;
然后对于x!
直接枚举2..x之间的那些质数;
然后i=p,p平方,p立方,p的4次方..那样加上n/i;
知道某个质数的指数之后,直接根据是分子还是分母,分别加上或减去那个∑(n/i)就好;
这样就不用1..x里面每个数都再去分解一次质因数了;

//直接暴力搞    for (int i = 1;i <= x;i++)    {        int x = i;        for (int j= 2;j*j <= x;j++)        while (x%j==0)        {            cnt[j]->change;            x/=j;        }    }
//更优雅的方法    for (int i = 2;i <= x;i++)    {        if (zhishu[i])        {            zhi=0            for (int j = i;j <= x;;j*=i)                zhi+=x/j;            cnt[i]->change(zhi);        }    }


【完整代码】

/**************************************************************    Problem: 1005    User: chengchunyang    Language: C++    Result: Accepted    Time:36 ms    Memory:1316 kb****************************************************************/#include <bits/stdc++.h>using namespace std;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define LL long long#define rep1(i,a,b) for (int i = a;i <= b;i++)#define rep2(i,a,b) for (int i = a;i >= b;i--)#define mp make_pair#define pb push_back#define fi first#define se second#define rei(x) scanf("%d",&x)#define rel(x) scanf("%I64d",&x)typedef pair<int,int> pii;typedef pair<LL,LL> pll;const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};const double pi = acos(-1.0);const int N = 1100;int n,d[N],m,tot,cnt[N];int ans[N],len = 1;bool bo[N];void go(int t,int x){    rep1(i,2,t)        if (bo[i])        {            int num = 0;            for (int j = i;j <= t;j*=i)                num+=t/j;            cnt[i]+=x*num;        }}void cheng(int p){    int x = 0;    rep1(i,1,len)    {        ans[i] = ans[i]*p+x;        x = ans[i]/10;        ans[i]%=10;    }    while (x>0)    {        ans[++len] = x;        x = ans[len]/10;        ans[len]%=10;    }}bool is(int x){    rep1(i,2,int(sqrt(x)))        if (x%i==0)            return false;    return true;}int main(){    //freopen("F:\\rush.txt","r",stdin);    rei(n);    rep1(i,1,n)    {        rei(d[i]);        if (d[i]==0) return puts("0"),0;        if (d[i]==-1)            m++;        else            d[i]--,tot+=d[i];    }    if (n-2<tot)        return puts("0"),0;    memset(bo,false,sizeof bo);    rep1(i,2,n-2)        if (is(i)) bo[i] = true;    go(n-2,1);    go(n-2-tot,-1);    rep1(i,1,n)        go(d[i],-1);    ans[1] = 1;    rep1(i,2,n)        rep1(j,1,cnt[i])            cheng(i);    rep1(i,1,n-2-tot)        cheng(m);    rep2(i,len,1)        printf("%d",ans[i]);    return 0;}
0 0
原创粉丝点击