用了一个简单的数论定理 百度了一下 可以看一下 然后二分求最小值
http://zhidao.baidu.com/question/542470152.html
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include <cstring> #include <iostream> #include <algorithm> #include <cstdio> using std::max; using std::cin; using std::cout; using std::endl; long long number[110],mx; bool prime[110]; void tot() { memset(prime, true, sizeof(prime)); prime[1]=false; for(int i=2; i<101; ++i) { if(prime[i]) { for(int j=i+i; j<101; j+=i) { prime[j]=false; } } } } void solve(long long a, long long b) { for(int i=2; i<=a; ++i) { if(prime[i]) { while(a%i==0 && a!=1 && a>=i) { number[i]+=b; a/=i; } } if(a==1) break; } } long long fins(int a,long long n) { long long sum=0; while(n) { sum+=n/a; n/=a; } return sum; } bool is_ok(long long x) { for(int i=2; i<101; ++i) { if(number[i] && prime[i]) { if(fins(i,x)<number[i]) return false; } } return true; } void fun() { long long l=0,r=(long long)1 << 60,mid; while(l<r) { mid=(l+r)/2; if(is_ok(mid)) r=mid; else l=mid+1; } printf("%I64d\n",l); } int main() { tot(); int t,n; long long a,b; scanf("%d",&t); while(t--) { memset(number, 0, sizeof(number)); mx=-1; scanf("%d",&n); for(int i=0; i<n; ++i) { scanf("%I64d %I64d",&a,&b); solve(a,b); } fun(); } return 0; }