首页 > 代码库 > HDU 3641 Treasure Hunting

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;
}