标签:ase for div 素数 cas 过程 sub while void
题意:T(<=1e4)组数据,求对于N(<=1e12),已知N在k进制表示下末位是0,求有多少个可能的k
相当与求解每个N的因数个数减1(代表除去1进制的情况)
N=p1a1*p2a2*...*pnan,若N=m*n,那么m可表示为m=x*p1^(k), 0 <= k <= a1,
那么N的约数个数为(a1+1)(a2+1)...(an+1)
对于不大于1e12的数,若它为素数,答案恒为1;若它不为素数,那么它必然可以被不大于1e6的数整除,所以我们只需要预处理出不大于1e6的素数表即可。
计算时求出每个素数的指数,不断累乘即可。注意最后如果N!=1,说明最后剩下的是素数,所以答案再乘2.代表指数0和1两种情况(类似于求欧拉函数的过程)
复杂度的话,π(1000000)=1000000/ln(1000000)=72383,最坏情况下约7*10^(8),推车.jpg
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define INF 0x3f3f3f3f 5 #define MOD 1000000007 6 typedef long long LL; 7 8 const int maxn = 1e6 + 10; 9 int prime[maxn]; 10 bool is_prime[maxn]; 11 12 int T; 13 LL N; 14 15 void init() { 16 for (int i = 0; i < maxn; i++) is_prime[i] = true; 17 is_prime[0] = is_prime[1] = false; 18 for (int i = 2; i < maxn; i++) { 19 if (is_prime[i]) { 20 prime[++prime[0]] = i; 21 for (int j = i + i; j < maxn; j += i) is_prime[j] = false; 22 } 23 } 24 } 25 26 int main() { 27 init(); 28 scanf("%d", &T); 29 for (int t = 1; t <= T; t++) { 30 scanf("%lld", &N); 31 LL ans = 1; 32 for (int i = 1; i <= prime[0] && (LL)prime[i] * prime[i] <= N; i++) { 33 LL tmp = 0; 34 while (N % prime[i] == 0) { 35 N /= prime[i]; 36 tmp++; 37 } 38 ans *= (tmp + 1); 39 } 40 if (N > 1) ans *= 2; 41 printf("Case %d: %lld\n", t, ans - 1); 42 } 43 return 0; 44 }
LightOJ - 1028 Trailing Zeroes (I)
标签:ase for div 素数 cas 过程 sub while void
原文地址:http://www.cnblogs.com/xFANx/p/7520777.html