fzu 1753 素数

题意:n组数a[i], b[i],令ti = C(a[i], b[i]) ,求t1 t2 t3....的最大公约数。

分析:C(a, b) = a! / b! / (a-b)! ,记录最小的a[i],  设为min,则公因子不可能比min大。

枚举公共素因子p, a!里p的个数为c1 = a/p+a/(p^2)+a/(p^3)...,  b!里p的个数为c2,(a-b)!为c3,则一共有ci = c1-c2-c3个p

c1 c2 c3...中最小值即为最大公约数中的p的个数。

 

 

const int M = 9592;
int prime[M]={2,3,5,7,11,13......99991};

int a[155],b[155],T;

int main(){
    while( ~scanf("%d", &T) ) {
        //int maxa=-1;
        int mina=10000000;
        FOR(j,0,T) {
            scanf("%d%d",&a[j],&b[j]);
            //checkmax(maxa,a[j]);
            checkmin(mina,a[j]);
        }
        long long ans = 1;

        FOR(i,0,M){
            int cnt = -1;
            int p = prime[i];

            //if(p > maxa) break;
            if(p > mina) break;//由于是求最大公约数,如果素数p比最小的a大   显然不是公因子
            
            FOR(j,0,T){
                //if(p > a[j]) continue;
                int c=0,temp = a[j];
                while(temp){ temp /= p; c += temp; }

                if(b[j] >= p) {
                    temp = b[j];
                    while(temp){ temp /= p; c -= temp; }
                }

                if(a[j] - b[j] >= p) {
                    temp = a[j] - b[j];
                    while(temp){ temp /= p; c -= temp; }
                }

                checkmin(cnt, c);
            }
            while(cnt--) ans*=p;
        }
        printf("%I64d\n",ans);
    }
    return 0;
}

 

posted @ 2013-05-29 22:19  心向往之  阅读(124)  评论(0编辑  收藏  举报