码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 3641 Treasure Hunting (二分+分解质因子)

时间:2014-07-29 14:43:08      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:hdu   二分   数论   素数   分解质因子   

题目链接:HDU 3641 Treasure Hunting

题意:求X!%M==0中最小的的X。其中M=a1^b1*a2^b2*a3^b3....

思路:求余为0想到整除,即分母的因子构成的集合是分子的因子构成的集合的子集。因子又想到,任何一个整数都可以分解成若干个素数相乘。

注意:题目数据很大,查到答案时二分。


AC代码:


#include<stdio.h>
#include<string.h>
#define ll __int64
bool Prime[210];
ll num[210];//M中的质因数个数

void getPrime()//素数打表
{
	int i,j;
	memset(Prime,true,sizeof Prime);
	Prime[0]=Prime[1]=false;
	for(i=2;i*i<=110;i++)
	{
		if(Prime[i])
		{
			for(j=i+i;j<=110;j+=i)
				Prime[j]=false;
		}
	}
}
void cal(ll a,ll b)//分解质因子
{
	ll i,n=a;
	for(i=2;i<=a;)
	{
		if(n%i==0 && Prime[i])
		{
			n/=i;
			num[i]+=b;
		}
		else
			i++;
	}
}
ll find(ll i,ll x) //x!中i的个数
{
	ll ans=0;
	while(x)
	{
		x/=i;
		ans+=x;
	}
	return ans;
}
bool ok(ll x)//
{
	ll i;
	for(i=1;i<=100;i++)
	{
		if(num[i])
		{
			ll temp=find(i,x);
			if(num[i]>temp) //分母的质因子个数比分子质因子大。
				return false;
		}
	}
	return true;
}
ll bfind()//二分查到答案
{
	ll ans=0;
	ll left,right,mid;
	left=0;
	right=ll(1)<<62;
	while(left<=right)
	{
		mid=(left+right)>>1;
		if(ok(mid))
		{
			ans=mid;//为了得到最小。
			right=mid-1;
		}
		else
			left=mid+1;
	}
	return ans;
}

int main()
{
	int t,n,i;
	ll a,b;
	getPrime();
	while(scanf("%d",&t)!=EOF)
	{
		while(t--)
		{
			memset(num,0,sizeof num);
			scanf("%d",&n);
			for(i=0;i<n;i++)
			{
				scanf("%I64d %I64d",&a,&b);
				cal(a,b);
			}
			ll ans=0;
			ans=bfind();
			printf("%I64d\n",ans);
		}
	}
	return 0;
}


HDU 3641 Treasure Hunting (二分+分解质因子),布布扣,bubuko.com

HDU 3641 Treasure Hunting (二分+分解质因子)

标签:hdu   二分   数论   素数   分解质因子   

原文地址:http://blog.csdn.net/u012377575/article/details/38235767

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!