1. 程式人生 > >noip模擬賽 SAC E#1 - 一道中檔題 Factorial

noip模擬賽 SAC E#1 - 一道中檔題 Factorial

因子 格式 nbsp 整數 100% ostream 沒有 說明 出現

題目背景

數據已修改

SOL君(爐石主播)和SOL菌(完美信息教室講師)是好朋友。

題目描述

SOL君很喜歡階乘。而SOL菌很喜歡研究進制。

這一天,SOL君跟SOL菌炫技,隨口算出了n的階乘。

SOL菌表示不服,立刻就要算這個數在k進制表示下末尾0的個數。

但是SOL菌太菜了於是請你幫忙。

輸入輸出格式

輸入格式:

每組輸入僅包含一行:兩個整數n,k。

輸出格式:

輸出一個整數:n!在k進制下後綴0的個數。

輸入輸出樣例

輸入樣例#1:
10 40
輸出樣例#1:
2

說明

對於20%的數據,n <= 1000000, k = 10

對於另外20%的數據,n <= 20, k <= 36

對於100%的數據,n <= 10^12,k <= 10^12

update

1.一組數據

2.K不會==1

3.現在std沒有爆long long

4.對數據有問題聯系icy (建議大家不要面向數據編程)

分析:k=10就是一個非常經典的問題,將n!分解質因數,看看有多少個5就可以了.現在考慮k≠10的情況,模擬一下進制轉換,就是不斷地%k,/k,我們就是要求一開始k能整除n!多少次.

n!,k過大,顯然不能直接算,涉及到倍數,我們可以分解一下k,看看k的質因子是不是n!都有,並且n中的次數大於等於k中的次數.假設n!有一個因子p1,次數為b1,它在k中的次數為b2,每做一次除法就是b1-=b2,每次做除法後都必須保證k中的質因子n!都有,並且次數不能小於k中的.能做多少次除法呢?把相同質因子的次數相除,取個min就可以了.

還有一個問題:k可以直接分解質因數,但是n!就非常大了,我們根本算不出來,怎麽才能統計k中的每個質因數在n!中出現的次數呢?對於一個質因數p,1~n個數中有n / p個數包含這個質因子,有n / (p ^ 2)個數包含p^2,也就是相當於包含了p.我們求出包含了p^i的個數,最後相加一下就是答案了.因為階乘嘛,最後乘起來等於指數的相加.

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>

using
namespace std; long long n, k; long long cnt, p[1000010], tot[1000010], ans = 10000000000000000; void f(long long x) { for (long long i = 2; i * i <= x; i++) { if (x % i == 0) { p[++cnt] = i; while (x % i == 0) { tot[i]++; x /= i; } } } if (x != 1) { p[++cnt] = x; tot[x]++; } } long long cal(long long x, long long y) { //printf("%lld %lld\n", x, y); if (y > x) return 0; return x / y + cal(x / y, y); } int main() { scanf("%lld%lld", &n, &k); f(k); for (int i = 1; i <= cnt; i++) ans = min(ans, cal(n, p[i]) / tot[p[i]]); printf("%lld\n", ans); return 0; }

noip模擬賽 SAC E#1 - 一道中檔題 Factorial