LightOJ 1340 - Story of Tomisu Ghost 阶乘分解素因子

时间:2022-03-10 03:32:23

 

http://www.lightoj.com/volume_showproblem.php?problem=1340

题意:问n!在b进制下至少有t个后缀零,求最大的b。

思路:很容易想到一个数通过分解素因子可以得到最大的指数。那么问题关键在于求得n!的素因子的指数,找到指数大于t的所有素因子,再将那些指数除去t,剩下的数就是最大的b了。分解阶乘时,对n不断除素数p,直到n为0时,此时商的和即该素因子的指数。

 

 

/** @Date    : 2016-11-30-19.35
  * @Author  : Lweleth (SoungEarlf@gmail.com)
  * @Link    : https://github.com/
  * @Version :
  */

#include<bits/stdc++.h>
#define LL long long
#define PII pair
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std;

const int INF = 0x3f3f3f3f;
const int N = 1e5+2000;
const int mod = 10000019;
LL pri[N];
int c = 0;
bool vis[N];

void prime()
{
    for(int i = 2; i < N; i++)
    {
        if(!vis[i])
        {
            for(int j = i + i; j < N; j+= i)
            {
                if(!vis[j])
                    vis[j] = 1;
            }
            pri[c++] = i;
        }
    }
}

LL fpow(LL a, LL n)
{
    LL r = 1;
    while(n > 0)
    {
        if(n & 1)
            r = r * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return r;
}

int main()
{
    prime();
    int T;
    int cnt = 0;
    cin >> T;
    while(T--)
    {
        LL n;
        LL r;
        cin >> n >> r;
        LL ans = 1;
        for(int i = 0; i < c && pri[i] <= n; i++)
        {
            LL t = n;
            LL ct = 0;
            while(t)
            {
                ct += t / pri[i];
                t /= pri[i];
            }
            if(ct >= r)
                ans = ans * fpow(pri[i], ct/r) % mod;
            if(ct < r)
                break;
        }
        if(ans == 1)
            printf("Case %d: -1\n", ++cnt);
        else
            printf("Case %d: %d\n", ++cnt, ans);
    }
    return 0;
}