Harry Potter and the Hide Story
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 2829 Accepted Submission(s): 718
Problem Description
iSea is tired of writing the story of Harry Potter, so, lucky you, solving the following problem is enough.
Input
The first line contains a single integer T, indicating the number of test cases.
Each test case contains two integers, N and K.
Technical Specification
1. 1 <= T <= 500
2. 1 <= K <= 1 000 000 000 000 00
3. 1 <= N <= 1 000 000 000 000 000 000
Each test case contains two integers, N and K.
Technical Specification
1. 1 <= T <= 500
2. 1 <= K <= 1 000 000 000 000 00
3. 1 <= N <= 1 000 000 000 000 000 000
Output
For each test case, output the case number first, then the answer, if the answer is bigger than 9 223 372 036 854 775 807, output “inf” (without quote).
Sample Input
2 2 2 10 10
Sample Output
Case 1: 1 Case 2: 2
解题思路:
把K分解质因素,求出每个因数在n!中有多少个,然后个数再除以该因素在K中的个数,去最小值就是答案了。
题目要求大于9 223 372 036 854 775 807要用inf输出,
9 223 372 036 854 775 807=2^63-1,用unsigned long long 存答案即可,K=1要特判。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<map>
#include<string>
#include<queue>
#include<vector>
#include<list>
#include<bitset>
//#pragma comment(linker,"/STACK:1024000000,1024000000")
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
ll K,n;
int prime[10000005],cur;
ll fac[105];
int num[105];
const ull INF = 9223372036854775808ull;
//500000000000000000
//999999999999999976
//9223372036854775808
void getfac(ll n)
{
fac[0]=0;
ll &cnt=fac[0];
for(int i=0;i<cur;i++)
{
if((ll)prime[i]*prime[i]>n) break;
if(n%prime[i]==0)
{
fac[++cnt]=prime[i];
num[cnt]=0;
while(n%prime[i]==0) n/=prime[i],num[cnt]++;;
}
}if(n>1) {fac[++cnt]=n;num[cnt]=1;}
}
ull get(ll d)
{
ull ans=0;
for(ull i=d;;i*=d)
{
ans+=n/i;
if(i>n/d) break;
}
return ans;
}
int main()
{
cur=0;
memset(prime,0,sizeof prime);
for(int i=2;i<10000005;i++)
{
if(!prime[i]) prime[cur++]=i;
for(int j=0;j<cur;j++)
{
if(i*prime[j]>=10000005) break;
prime[i*prime[j]]=1;
if(i%prime[j]==0) break;
}
}
int t,tt=0;
scanf("%d",&t);
while(t--)
{
scanf("%I64d%I64d",&n,&K);
ll Max=0;
if(K==1)
{
printf("Case %d: inf\n",++tt);
continue;
}
getfac(K);
ull Min=INF;
for(int i= 1;i<=fac[0];i++)
{
ull cnt=get(fac[i]);
cnt/=num[i];
Min=min(Min,cnt);
}
if(Min>=INF) printf("Case %d: inf\n",++tt);
else printf("Case %d: %I64u\n",++tt,Min);
}
return 0;
}