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 <cstdio>
using namespace std;
const int maxn = 110;
typedef long long LL;
bool vis[maxn];
int p[maxn],cnt;
LL a[maxn];
LL b[maxn];
LL num[maxn];

void init(){
    cnt = 0;
    memset(vis,0,sizeof(vis));
    for(int i=2;i<maxn;i++){
        if(!vis[i]){
            p[cnt++]=i;
            for(int j=i+i;j<maxn;j+=i)
                vis[j]=1;
        }
    }
}

LL get_num(LL x,int pri){
    if(x<pri) return 0;
    return get_num(x/pri,pri)+(LL)x/pri;
}

bool check(LL x){
    for(int i=0;i<cnt;i++){
        if(get_num(x,p[i])<num[p[i]])
            return false;
    }
    return true;
}

int main()
{
    init();
    int t,n;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        memset(num,0,sizeof(num));
        for(int i=0;i<n;i++){
            scanf("%I64d%I64d",a+i,b+i);
            int tmp = a[i];
            for(int j=0;p[j]*p[j]<=tmp&&j<cnt;j++){
                if(tmp%p[j]==0){
                    LL tot=0;
                    while(tmp%p[j]==0) tmp=tmp/p[j],tot++;
                    num[p[j]]+=tot*b[i];
                }
            }
            if(tmp>1) num[tmp]+=b[i];
        }
        LL ans = 0;
        for(int i=0;i<maxn;i++)
            ans=max(ans,(LL)i*num[i]);
        LL l=0,r=ans;
        while(l<=r){
            LL mid=(l+r)>>1;
            if(check(mid)) r=mid-1;
            else l=mid+1;
        }
        printf("%I64d\n",l);
    }
    return 0;
}
/*
111
6
6 1000000000000
15 1000000000000
13 1000000000000
7 1000000000000
2 1000000000000
3 1000000000000
*/

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-09-29 05:02:47

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 (二分+分解质因子)

题目链接: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 nu

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使得满足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 3468 Treasure Hunting(BFS+网络流之最大流)

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

HDU 3468 Treasure Hunting (最大流SAP)经典(看似广搜实则最大流)

Treasure Hunting Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 1532    Accepted Submission(s): 400 Problem Description Do you like treasure hunting? Today, with one of his friend, iSea is on

hdu 3468 Treasure Hunting

二分图匹配 题意: ... 看了半天 我们可以从rally点出发到最近的rally点, 如果有treasure在这两个rally点的最短路径上, 我们可以拿走他. 思路也可以参见http://blog.csdn.net/wall_f/article/details/8990937 这种分析问题的思路太值得学习了.. 一开始没看懂题.. 在vj上找了个代码 (o(╯□╰)o.. 谴责一下自己..)然后写了一下注释.. 写完注释发现就那么回事 不想再敲一遍了..噗.. 1 /*Author :use

【网络流】 HDU 3468 Treasure Hunting

题意: A-Z&&a-z 表示 集结点 从A点出发经过 最短步数 走到下一个集结点(A的下一个集结点为B ,Z的下一个集结点为a) 的路上遇到金子(*)则可以捡走(一个点只能捡一次) 求从A点出发走遍所有的的集结点 最多能捡多少金子 思路:先对于第 i 个集结点用BFS求出 对于每个点从该集结点所需的步数  为D[ I ] [ t ] 对于任意一个金子若  两个相邻的集结点的最短步数=其到该金子的步数和 则建一条边(可以拿) 然后最大流求 #include <cstdio> #

Treasure Hunting (hdu 3468 二分匹配+bfs最短路径)

Treasure Hunting Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 1509    Accepted Submission(s): 393 Problem Description Do you like treasure hunting? Today, with one of his friend, iSea is on