码迷,mamicode.com
首页 > 其他好文 > 详细

FZU2164 Jason's problem

时间:2015-06-10 09:00:25      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:acm   数论   fzu   

题目非常好懂,题意是给你n!和k个后缀零数,让你求出符合条件的进制b的个数。
假设你已经会求n!的质因数分解,再解释第一组样例。n=10,k=2,n!的阶乘可以表示为2^8*3^4*5^2*7,再转换成这种形式(2^4*3^2*5)^2*7,可以知有多少种进制满足条件,就是2^4*3^2*5的组合,一共有5*3*2种,其中肯定有不满足条件的,2^0,2^1,2^2,3^0,3^1,5^0,一共有3*2*1种,30-6等于24种。为什么不满足条件呢,因为如果有那种进制就会产生多余的0。

代码如下

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 10000;
typedef long long LL;
const LL mod = 1000000000+7;
int T;
LL n,k;
int Pri[maxn],num[maxn],vis[maxn];
int cnt=1;
int prime()
{
    memset(vis,0,sizeof vis);

    for(int i = 2; i<10000; i++)
        if(!vis[i])
        {
            Pri[cnt++]=i;
            for(int j=i+i; j<10000; j+=i)
                vis[j]=1;
        }
}
int solve(int n,int p)
{
    if(n<p)return 0;
    return n/p+solve(n/p,p);
}

int main()
{
    prime();
//    for(int i=1; i<=cnt; i++)
//        printf("%d\n",Pri[i]);
    scanf("%d",&T);
    while(T--)
    {
        memset(num, 0, sizeof num);
        scanf("%I64d%I64d",&n,&k);
        LL ans =1 , ans1 = 1;
        int i;
        for(i=1; i<=cnt; i++)
        {
            int tt = n;
            num[i]=solve(tt,Pri[i]);
            if(num[i]>=k)
            {
                LL temp = num[i]/k+1;
                ans = (ans*temp)%mod;
                LL temp1 = temp-1;
                int js=0;
                for(int j=1 ; j<=temp1; j++)
                {
                    if(num[i]/j!=k)
                        js++;
                }

                ans1 = (ans1*(js+1))%mod;
//                printf("%I64d\n",ans1);
            }
            else break;
        }
        printf("%I64d\n",((ans-ans1)%mod+mod)%mod);
    }

}

FZU2164 Jason's problem

标签:acm   数论   fzu   

原文地址:http://blog.csdn.net/zh9406/article/details/46432583

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!