求最大的k 使得 m^k 能被n!整除
m^k就是讓m的每個質因子個數增加了k倍,只要求得n!的質因子能讓m增加多少倍就夠了。當然這裏要取增加倍數最少的。
木桶裝水的量取決於最短的木板。
預處理2-n每個數的質因子情況,由於n有10000,前10000個素數有1000+個,所以維護前綴和不划算。
case只有500 所以乾脆每次都算一遍。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<math.h>
#include<algorithm>
#include<stdlib.h>
#include<time.h>
#include<vector>
#include<map>
using namespace std;
struct node
{
int x,t;
}t,tzf[100001];
vector<node> v[100001];
vector<int> pri;
int id[100011];
bool vis[100011];
void sieve()
{
int m= (int)sqrt(200001+0.5);
memset(vis,0,sizeof(vis));
for(int i=2;i<=m;i++)
{
if(!vis[i])
{
for(int j=i*i;j<=10000;j+=i)
vis[j]=1;
}
}
for(int i=2;i<=10000;i++)
{
if(!vis[i])
{
pri.push_back(i);
}
}
}
void init(int n)
{
int id=n;
for(int i=0;pri[i]*pri[i]<=n&&i<pri.size();i++)
{
if(n%pri[i]==0)
{
t.x=pri[i];
t.t=1;
n/=pri[i];
while(n%pri[i]==0)
{
n/=pri[i];
t.t++;
}
v[id].push_back(t);
}
}
if(n>1)
{
t.x=n;
t.t=1;
v[id].push_back(t);
}
}
int sum[100005];
int main()
{
sieve();
for(int i=2;i<=10000;i++)
init(i);
int cas;
scanf("%d",&cas);
int ca=1;
while(cas--)
{
int n,m;
memset(sum,0,sizeof(sum));
scanf("%d%d",&n,&m);
printf("Case %d:\n",ca++);
int top=0;
for(int i=2;i*i<=n;i++)
{
if(n%i==0)
{
n/=i;
tzf[top].x=i;
tzf[top].t=1;
while(n%i==0)
{
n/=i;
tzf[top].t++;
}
top++;
}
}
if(n>1)
{
tzf[top].x=n;
tzf[top].t=1;
top++;
}
for(int i=2;i<=m;i++)
{
for(int j=0;j<v[i].size();j++)
{
int tmp=v[i][j].x;
int ttmp=v[i][j].t;
sum[tmp]+=ttmp;
}
}
int ans=0x7fffffff;
for(int i=0;i<top;i++)
{
int tmp=tzf[i].x;
int ttmp=tzf[i].t;
ans=min(ans,sum[tmp]/ttmp);
}
if(ans==0||ans==0x7fffffff) puts("Impossible to divide");
else cout<<ans<<endl;
}
return 0;
}
/*
1234
2 10
2 100
97 12
*/