UVA11802-All Your Bases Belong to Us

来源:互联网 发布:淘宝代运营公司诈骗 编辑:程序博客网 时间:2024/06/04 18:24

All Your Bases Belong to Us

It is very easy to find number of trailing zero in n! for a
particular base b. In this problem you have to do the reverse.
You have to find for how many bases b, n! has k trailing zeros
in base b.
Input
Input starts with a positive number T ≤ 10000, denoting the
number of test cases to follow.
Each test case contains two non-negative integers, n ≤
1015 and 1 ≤ k ≤ 1015 in a line. You may assume that n/k < 500.
Output
For each input output one line containing the number of different bases. Print the solution modulo
1000000007
Sample Input
5
10 2
10 3
10 4
10 5
10 8
Sample Output
Case 1: 24
Case 2: 0
Case 3: 4
Case 4: 0
Case 5: 1

题目大意:给定n,k。求有多少个b满足在b进制下n!的表示恰以k个0结尾。
数据范围:n1015,k1015,n/k500
解题思路:fun(k)表示对于某数bn!|bkb的个数
则所求结果为fun(k)fun(k+1)
因为b=pk11pk22pkmm
又因为n!|bk
那么对于质因数pin!就至少要含有k×kipi
通过求n!b的个数的算法可得
knb+nb2+
knb1
bnk+1
结合数据范围,b不会超过501
所以可以筛选出501以内的素数,记录n!中含有这些素数中第i个的个数pownum[i](至少要大于等于k
所以k×kipownum[i]
kipownum[i]/k
所以pi的指数有
pownum[i]/k+1种选择
利用乘法原理即可求出b的个数

#include<iostream>#include<cstdio>#include<vector>#include<cstring>#include<queue>using namespace std;typedef long long LL;const int MAXN=505;const LL mod=1000000007;int prime[MAXN];LL pownum[MAXN];LL n,k;int bound;void getprime()//素数筛选{    memset(prime,0,sizeof(prime));    for(int i=2;i<=MAXN;i++)    {        if(!prime[i]) prime[++prime[0]]=i;        for(int j=1;j<=prime[0]&&prime[j]<=MAXN/i;j++)        {            prime[prime[j]*i]=1;            if(i%prime[j]==0) break;        }    }}//对于某数b,n!|b^k的b的个数LL fun(LL k){    LL ans=1;    for(int i=1;i<=bound;i++)    {        ans*=(pownum[i]/k+1);//乘法原理        ans%=mod;    }    return ans;}LL cal(int i)//求n!含有prime[i]的个数{    LL exp=0;    LL tmp=n;    while(tmp)    {        tmp/=prime[i];        exp+=tmp;    }    return exp;}int main(){    ios::sync_with_stdio(false);    getprime();//    cout<<prime[0]<<endl;//    for(int i=1;i<=96;i++)//    {//        cout<<prime[i]<<" ";//        if(i%10==0) cout<<endl;//    }    int T;    cin>>T;    int cas=0;    while(T--)    {        cin>>n>>k;        for(int i=1;i<=96;i++)//503 第96个素数        {            pownum[i]=cal(i);            if(pownum[i]<k)            {                bound=i-1;                break;            }        }        cout<<"Case "<<++cas<<": "<<((fun(k)-fun(k+1)%mod+mod))%mod<<endl;    }    return 0;}
阅读全文
1 0
原创粉丝点击