题意:
求最小的x!使得x!>= a1^b1*a2^b2*a3^b3.......;
思路:
a总是在100以内的,所以分解质因数,保存其各个质因数的个数即可保存下来这个very big的大数;
然后二分x,求解最小的x即可。
代码如下:
typedef long long LL;
typedef unsigned long long LLU;
const int M = 105;
int prime[M];
bool vis[M];
void getprime()
{
int tot = 0;
memset(vis,0,sizeof(vis));
memset(prime,0,sizeof(prime));
for(int i = 2; i < M; ++i)
{
if(!vis[i]) prime[tot++] = i;
for(int j = 0; j < tot; ++j)
{
if(i*prime[j]>=M) break;
vis[i*prime[j]] = true;
if(i%prime[j]==0) break;
}
}
}
LL cnt[M];
void divide(LL a, LL x)
{
for(int i = 0; a && prime[i]<=a; ++i)
{
if(a%prime[i]==0)
{
while(a%prime[i]==0)
{
cnt[prime[i]]+=x;
a/=prime[i];
}
}
}
}
LL getM(LL x, int a)
{
LL ans = 0;
while(x)
ans += (x/=a);
return ans;
}
bool ok(LL x)
{
for(int i = 0; prime[i]; ++i)
{
LL tmp = getM(x, prime[i]);
if(tmp<cnt[prime[i]])
return false;
}
return true;
}
int main()
{
int t, n;
LL a, b;
scanf("%d", &t);
getprime();
while(t--)
{
memset(cnt, 0, sizeof(cnt));
scanf("%d", &n);
for(int i = 0; i < n; ++i)
{
scanf("%I64d%I64d", &a, &b);
divide(a,b);
}
LL L = 0, R = (1LLU<<63)-1, Mid;
while(L<R)
{
Mid = (R-L)/2+L;
if(ok(Mid))
R = Mid;
else
L = Mid+1;
}
printf("%I64d\n", L);
}
return 0;
}