我们这样的菜鸟也有机会上网络赛了,这次杭州赛算是发挥了水准,要数一点小小的瑕疵就是忘记把变量t改成int64的,导致WA2次
先说说思路吧,先打一个素数表,把每一个底数分解因式,把含有素数因子i的数目加到aaa[i]上,这样就求出了总乘积M包含的因子以及这些因子的数量。接下来,只要枚举每一个因子,看满足含有aaa[i]个因子i 的最小阶,输出其中最大的一个。
//hdu3641
#include<iostream>
using namespace std;
int prime[100],k,temp[100];
bool sel[100];
void makeprime()//打素数表
{
int i,j,k;
memset(sel,0,sizeof(sel));
for(i=4;i<=100;i+=2)
sel[i]=1;
j=2,i=0;
while(j<=100)
{
prime[i++]=j;
j++;
while(sel[j]&&j<=100)
j++;
k=j*3;
while(k<=100){
sel[k]=1;
k+=2*j;
}
}
prime[i]=-1;
}
int main()
{
int i,j,k,c,m;
makeprime();
__int64 aaa[100],log2[100][50],temp,a,b,t,result,sum,n[100][50];
//aaa[]:因子的个数。n[i][j]: 因子i的j次方,log2[i ][j]:因子i的j次方的阶乘含多少个因子i。
//对于某个因子x,log2[x][j] 可以用log2[x][j]=log2[x][j-1]+n[x][j-1]确定
for(i=0;prime[i]!=-1;i++)
{
t=prime[i];
n[t][0]=t;
for(j=1;j<50;j++)
n[t][j]=n[t][j-1]*t;
}
for(i=0;prime[i]!=-1;i++)
{
t=prime[i];
log2[t][0]=1;
for(j=1;j<50;j++)
log2[t][j]=log2[t][j-1]+n[t][j-1];
}
cin>>c;
while(c--)
{
scanf("%d",&m);
result=result=0;
memset(aaa,0,sizeof(aaa));
for(i=0;i<m;i++)
{
scanf("%I64d%I64d",&a,&b);
if(a==1)
continue;
j=0,t=a;
for(k=0;t>1;k++){
if(t%prime[k]==0)
{
temp=0;
while(t%prime[k]==0){
t/=prime[k];
temp++;
}
aaa[prime[k]]+=b*temp;
}
}
}
for(i=2;i<100;i++)
{
if(aaa[i]){
t=aaa[i];
for(j=0;log2[i][j] <= t;j++);
j--;
sum=n[i][j];
temp=t-log2[i][j];
while(j>=0){
while(log2[i][j] <= temp){
temp-=log2[i][j];
sum+=n[i][j];
}
j--;
}
if(sum>result)
result=sum;
}
}
printf("%I64d/n",result);
}
return 0;
}