时间限制:500MS 内存限制:1000K
提交次数:189 通过次数:46
题型: 编程题 语言: G++;GCC
Description
游戏玩了很久总会厌的,连Lyd的蚂蚁都被放生了......(参看题目:盒子上的蚂蚁) 于是Mr.Chen 看大家很无聊,就让Lord.Suno 负责新生赛出题的事情,然后大家一起帮忙出题。 Lyd 想了很久,想到一个题目,题意如下: 给出两个数,正整数n(n<10)和质数m(m<100),求满足n!=k * m^p 最大的整数p(k 为正 整数)。 题目拿给Suno看,他说,这也太简单了吧......三秒钟写完核心代码: sum=1;p=0; for(i=1;i<=n;i++) sum*=i; while(sum%m==0) { p++; sum/=m; } Lyd 想,那n<1000 吧,这样sum太大就存不下了。。。Suno 说,那也简单,不存直接算,就算你来 个10000 的也不怕。十秒钟的事情: p=0; for(i=1;i<=n;i++) { q=i; while(q%m==0) { p++; q/=m; } } -_-!!! 无奈之下Lyd 说,那m 不要质数了,不能直接除,然后增大规模,2<=m<5000,您能算不?Suno 想了想,说稍微处理一下,然后多用几次上面的代码,执行完再!@#$%^&*,就OK 啦...... 被Suno 多次BS 之后,Lyd 说,好吧,n<10^8,用扫描1-n 的方法超时,不让你扫......Suno 说, 呃,这样会不会太难......Lyd 得意地笑了,嘿嘿这回不会了吧!Suno 回了一句,不用for 用另一种更快 的方法而已,m<10^6 都没问题,我的意思是这思路有点巧妙,当新生赛会不会太难?也行,就这样吧, 相信想得到的,反正题目是你出的,没人做得出是你郁闷。。。Lyd 再次囧......
输入格式
测试数据第一行是一个数T(T<=10000),表示测试数据的组数。 之后每一行代表一组测试数据。 每一组测试数据有两个数,n(0<n<10^8)和m(2<=m<10^6)。
输出格式
对于每组测试数据,输出一行,每行一个数,能满足n!=k * m^p 的最大的p。
输入样例
2 4 6 6 3
输出样例
1 2
提示
来源
lyd
作者
adminpp教了我怎么方便的唯一分解后这道题就算很水了
题目实际就是要你求从1*2*3*。。n中,能够乘出多少个m,那么我们可以把m唯一分解,对于m的每个质因数k,其个数为p,在n!中k的个数可以快速求出,为c,那么c/p就是一个可能的答案,在所有的可能答案中取一个最小的就好了
求n!中k的个数?还记得求n!中末尾0的个数吗,其实就是求10的个数,其实就是求2和5的个数。。。。。。
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int N = 1e6; typedef long long ll; int n, m, c; int fr[N], p[30], mp[30]; int pri[N]= {0}; int pnum = 0; void pre() { for(int i = 2; i < N; ++i) { if(!fr[i]) { pri[ pnum++ ] = i; fr[i] = i; } for(ll j = 0; j < pnum && i * pri[j] < N; ++j) { fr[i * pri[j]] = pri[j]; if(!(i % pri[j])) break; } } } void get(int x) { /// 对x唯一分解,mp存储质因数序列,p存储每个质因数对应的个数 c = 0; int t = -1; while(x > 1) { if(fr[x] != t) { c++; mp[c] = fr[x]; } p[c]++; t = fr[x]; x /= fr[x]; } } int calc(int k) { ///求1~n中能组成的k的个数 int cnt = 0; ll mult = k; while(mult <= n) { cnt += n / mult; mult = mult * k; } return cnt; } int main() { pre(); int _; scanf("%d", &_); while(_ --) { scanf("%d%d", &n, &m); memset(p, 0, sizeof p); get(m); int ans = 0x3f3f3f3f; for(int i = 1; i <= c; ++i) { ans = min(ans, calc(mp[i]) / p[i]); } printf("%d ", ans); } return 0; }