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

题目链接: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 (二分+分解质因子)

时间: 2024-10-11 23:28:10

HDU 3641 Treasure Hunting (二分+分解质因子)的相关文章

hdu 3641 Treasure Hunting 强大的二分

1 /** 2 大意:给定一组ai,bi . m = a1^b1 *a2^b2 * a3^ b3 * a4^b4*...*ai^bi 3 求最小的x!%m =0 4 思路: 将ai 质因子分解,若是x!%m=0 那么x! 质因子分解之后 质因子的个数一定大于等于m的个数.二分求解可得 5 注意: 二分时,需要将,上下限 设定好,low =0: high = 1ll<<60; 6 **/ 7 8 #include <iostream> 9 #include <cstring&g

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 计算并储存好个个质数的次方 #includ

HDU 3641 Treasure Hunting (素数拆分)

题意:有N个ai,bi,M=a1^b1*a2^b2*a3^b3-*an^bn ,求最小的 x 使得 x! % M ==0. 思路:把M分成多个素数相乘,num[i] 记录素数 i 的个数,然后二分找到x,若 x! 中所有 i 的个数满足>=num[i] 即为答案. #include<cstdio> #include<stdlib.h> #include<string.h> #include<string> #include<map> #in

HDU 3641 Treasure Hunting(阶乘素因子分解+二分)

题目链接:传送门 题意: 求最小的 ( x! ) = 0 mod (a1^b1*a2^b2...an^bn) 分析: 首先吧a1~an进行素因子分解,然后统计下每个质因子的指数,由于随着x的增大,质因子的个数是逐渐增加的 因此我们可以二分x,对x!进行素因子分解判断是否满足条件,然后求出最小的就可以了. 代码如下: #include <iostream> #include <cstring> #include <algorithm> #include <cstdi

HDU 4135 Co-prime (容斥+分解质因子)

<题目链接> 题目大意: 给定区间[A,B](1 <= A <= B <= 10 15)和N(1 <=N <= 10 9),求出该区间中与N互质的数的个数. 解题分析: 将求区间[A,B]与N互质的数转化成求[1,B] 区间与N互质的个数  -  [1,A-1]中与N互质的个数.同时,因为直接求区间内与N互质的数不好求,我们从反面入手,求出与N不互质的数,借鉴埃筛的思想,我们先求出N的所有质因子,然后将这些质因子在区间内倍数的个数全部求出(即与N不互质的数),再用

HDU 4497 GCD and LCM(分解质因子+排列组合)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4497 题意:已知GCD(x, y, z) = G,LCM(x, y, z) = L.告诉你G.L,求满足要求的(x, y, z)有多少组,并且要考虑顺序. 思路:如果L%G != 0显然不存在这样的(x, y, z),相反肯定存在.具体做法就是将L/G分解质因子,得到:L/G = P1^t1 * P2^t2 * ... * Pk^tk,我们来考虑任意一个因子Pi^ti,此时(x/G, y/G, z/

HDU 3468 Treasure Hunting(BFS+网络流之最大流)

题目地址:HDU 3468 这道题的关键在于能想到用网络流.然后还要想到用bfs来标记最短路中的点. 首先标记方法是,对每一个集合点跑一次bfs,记录所有点到该点的最短距离.然后对于任意一对起始点来说,只要这个点到起点的最短距离+该点到终点的最短距离==起点到终点的最短距离,就说明这点在某条从起点到终点的最短路上. 然后以集合点建X集,宝物点建Y集构造二分图,将从某集合点出发的最短路中经过宝物点与该集合点连边.剩下的用二分匹配算法或最大流算法都可以.(为什么我的最大流比二分匹配跑的还要快....

分解质因子(个人模版)

分解质因子: 1 memset(prime,0,sizeof(prime)); 2 memset(num,0,sizeof(num)); 3 for(int i=2;i<=5000005;i++) 4 { 5 if(prime[i]==0) 6 { 7 for(int j=i;j<=5000005;j+=i) 8 { 9 int temp=j; 10 while(temp%i==0) 11 { 12 num[j]++; 13 temp/=i; 14 } 15 prime[i]=1; 16 }

UVA10892 - LCM Cardinality(分解质因子)

题目链接 题意:输入正整数n,统计有多少对正整数a <= b,满足lcm(a, b) = n. 思路:分解质因子,然后直接暴力求出对数 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; typedef long long ll; const int MA