Codeforces Round #538 (Div. 2) C. Trailing Loves

Description:

给出n和b,问n!在b进制下末尾有多少个相连的0,比如6!(10)=720(10)=880(9). 所以6!在9进制下有1个0

Input:

n,b

Output:

answer

Analysis:

实际上是求n!的因数中有b^k,k的最大值为多少。可以用唯一分解定理,同时分解为质数然后判断,可以先对b进行质因数分解,然后求n对于每个b的质因数的次数,假设要求n!中质因数s的次数为多少,这里可以直接使用cnt=[n/s]+[n/s^2]+[n/s^3]+...

这样分别算的是1到n中s,s^2,s^3这些因数对答案的贡献。最后只要对n和b的相应质因数次数进行比较跟新答案即可

#define _CRT_SECURE_NO_WARNINGS  
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<sstream>
#include<cmath>
#include<iterator>
#include<bitset>
#include<stdio.h>
#include<unordered_set>
#include<ctime>
#include<cstring>
using namespace std;
#define _for(i,a,b) for(int i=(a);i<(b);++i)
#define _rep(i,a,b) for(int i=(a);i<=(b);++i)
typedef long long LL;
const int INF = 1 << 30;
const int maxn = 1e6+5;
const int MOD = 1e9+7;
const double eps = 1e-6;

LL n, b;
map<LL,LL> b_;
map<LL,LL> n_;

int main()
{
	//freopen("C:\\Users\\admin\\Desktop\\in.txt", "r", stdin);
	//freopen("C:\\Users\\admin\\Desktop\\out.txt", "w", stdout);
	while (cin >> n >> b) {
		LL bb = b;
		b_.clear(); n_.clear();
		LL  can = sqrt(b) + 1;//所有质数的范围 
		for (LL i = 2; i < can; ++i)//遍历 
		{
			LL cnt = 0;
			while (b%i == 0)//对于每个可以约去的数字 
			{
				cnt++;
				b = b / i;//相除
			}
			if (cnt > 0) b_[i] = cnt;
		}
		if(b!=1) b_[b] = 1;
		LL ans = 0x3f3f3f3f3f3f3f3fLL;
		for (auto it : b_) {
			LL cnt = 0, tmp = it.first;
			LL nn = n;
			while (nn) { cnt+=nn/tmp; nn/= it.first; }
			n_[it.first] = cnt;
			ans = min(ans, n_[it.first] / b_[it.first]);
		}
		cout <<ans<<endl;
	}

	return 0;
}

猜你喜欢

转载自blog.csdn.net/tomandjake_/article/details/87001791
今日推荐