hdu 3641 - Treasure Hunting(筛素数+二分)

题意:

求最小的x!使得x!>= a1^b1*a2^b2*a3^b3.......;

思路:

a总是在100以内的,所以分解质因数,保存其各个质因数的个数即可保存下来这个very big的大数;

然后二分x,求解最小的x即可。

代码如下:

typedef long long LL;
typedef unsigned long long LLU;
const int M = 105;

int prime[M];
bool vis[M];

void getprime()
{
    int tot = 0;
    memset(vis,0,sizeof(vis));
    memset(prime,0,sizeof(prime));
    for(int i = 2; i < M; ++i)
    {
        if(!vis[i]) prime[tot++] = i;
        for(int j = 0; j < tot; ++j)
        {
            if(i*prime[j]>=M) break;
            vis[i*prime[j]] = true;
            if(i%prime[j]==0) break;
        }
    }
}
LL cnt[M];
void divide(LL a, LL x)
{
    for(int i = 0; a && prime[i]<=a; ++i)
    {
        if(a%prime[i]==0)
        {
            while(a%prime[i]==0)
            {
                cnt[prime[i]]+=x;
                a/=prime[i];
            }
        }
    }
}
LL getM(LL x, int a)
{
    LL ans = 0;
    while(x)
        ans += (x/=a);
    return ans;
}
bool ok(LL x)
{
    for(int i = 0; prime[i]; ++i)
    {
        LL tmp = getM(x, prime[i]);
        if(tmp<cnt[prime[i]])
            return false;
    }
    return true;
}
int main()
{
    int t, n;
    LL a, b;
    scanf("%d", &t);
    getprime();
    while(t--)
    {
        memset(cnt, 0, sizeof(cnt));
        scanf("%d", &n);
        for(int i = 0; i < n; ++i)
        {
            scanf("%I64d%I64d", &a, &b);
            divide(a,b);
        }
        LL L = 0, R = (1LLU<<63)-1, Mid;
        while(L<R)
        {
            Mid = (R-L)/2+L;
            if(ok(Mid))
                R = Mid;
            else
                L = Mid+1;
        }
        printf("%I64d\n", L);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值