HDU 3641 Treasure Hunting

用二分查找来找到一个X使得满足X!%M==0

M=a1^b1*a2^b2*a3^b3…*an^bn

X!=1*2*3*4*5....*X;

M可以化为其个个质因子的k次方的乘积

例如 2^3*3^2*4^5==2^13*3^2;

X!则可以得到 

  例如 2的次方为 X! = 2^(X/2)*(1*2*3*4*5*6*7....*X/2)*other=(x/2)! *other;

继续计算知道x/2==1为止 得到次方数;再与输入的数比较

输入的ai,bi 计算并储存好个个质数的次方


#include<stdio.h>
#include<string.h>
#include <stdlib.h>
#include <limits.h>
#include<algorithm>
#include<math.h>
#include<queue>
typedef __int64 LL;
using namespace std;
LL num[101];
LL out(LL  x,int n)
{
    LL  sum=0;
    while(x){
        sum+=x/n;
        x/=n;
    }
    return sum;
}
bool find(LL x)
{
    for(LL i=2;i<=100;i++)
    {
        if(num[i]>0)
        {
            if(out(x,i)<num[i])//若出现小于
                return false;
        }
    }
    return true;
}
int main()
{
    int n,t;
    //freopen("in.txt","r",stdin);
    scanf("%d",&t);
    while(t--)
    {
        memset(num,0,sizeof(num));
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            int a;
            LL b;
            scanf("%d%I64d",&a,&b);
            while(a!=1)
                for(int i=2;i<=a;i++)//计算素数因子的次方数
                    if(a%i==0)
                    {
                        num[i]+=b;
                        a/=i;
                        break;
                    }
        }
        LL l=0,r;
        r=(LL)1 << 63-1;
        while(l<=r)//二分x
        {
            LL mid=(l+r)>>1;
            if(find(mid))
               r=mid+1;
            else l=mid-1;
        }
        printf("%I64d\n",l);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值