描述
传送门: F. Divisions
David is a young boy and he loves numbers. Recently he learned how to divide two numbers. David divides the whole day. He is happy if the result of the division is an integer, but he is not very amused if this is not the case. After quite a while he decided to use only a single dividend each day.
The parents of David are very careful and they would like to ensure that David experiences enough happiness. Therefore they decide which number David will use as the dividend for this day.
There is still a problem: The parents are not very good at math and don’t know how to calculate the number of positive integral divisors for a given dividend N , which lead to an integral result. Now it’s up to you to help David’s parents.
输入
The single input line contains the single integer N , where N is chosen as a dividend (1 ≤ N ≤ 1018 ).
输出
Print the number of positive integral divisors of N that lead to an integral result of the division.
样例
输入
12
输出
6
输入
999999999999999989
输出
2
输入
100000007700000049
输出
4
思路
由于数据规模太大,因此无法用常规的解题方法来求出答案
题意是让求出给出数字的质因数个数
因此使用Miller_Rabin算法+Pollard_rho算法+质因数求解公式来计算
ps:这两个算法我也是刚学到,感觉有些难懂
代码
1 /* 2 * ========================================================================= 3 * 4 * Filename: G.cpp 5 * 6 * Link: https://nanti.jisuanke.com/t/28395 7 * 8 * Version: 1.0 9 * Created: 2018/07/14 20时04分58秒 10 * Revision: none 11 * Compiler: g++ 12 * 13 * Author: 杜宁元 (https://duny31030.github.io/), duny31030@126.com 14 * Organization: QLU_浪在ACM 15 * 16 * ========================================================================= 17 */ 18 #include <bits/stdc++.h> 19 using namespace std; 20 #define ll long long 21 #define max3(a,b,c) fmax(a,fmax(b,c)) 22 #define ios ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0); 23 const double eps = 1e-6; 24 const int INF = 0x3f3f3f3f; 25 const ll NUM = 10; // 运算次数,误判率为2^(-NUM) 26 ll t,f[100]; 27 28 ll mul_mod(ll a,ll b,ll n) // 求a*b%n,由于a和b太大,需要用进位chengfa 29 { 30 a = a%n; b = b%n; 31 ll s = 0; 32 while(b) 33 { 34 if(b&1) 35 s = (s+a)%n; 36 a = (a << 1) %n; 37 b = b >> 1; 38 } 39 return s; 40 } 41 42 ll pow_mod(ll a,ll b,ll n) // 求a^b%n 43 { 44 a = a%n; 45 ll s = 1; 46 while(b) 47 { 48 if(b&1) 49 s = mul_mod(s,a,n); 50 a = mul_mod(a,a,n); 51 b = b >> 1; 52 } 53 return s; 54 } 55 56 ll check(ll a,ll n,ll r,ll s) 57 { 58 ll ans = pow_mod(a,r,n); 59 ll p = ans; 60 for(ll i = 1;i <= s;i++) 61 { 62 ans = mul_mod(ans,ans,n); 63 if(ans == 1 && p != 1 && p != n-1) 64 return true; 65 p = ans; 66 } 67 if(ans != 1) 68 return true; 69 return false; 70 } 71 72 ll gcd(ll a,ll b) 73 { 74 return b == 0 ? a : gcd(b,a%b); 75 } 76 77 // Miller_Rabin算法 78 // 判定一个大数是否是素数 79 bool Miller_Rabin(ll n) 80 { 81 if(n < 2) return false; 82 if(n == 2) return true; 83 if(!(n&1)) return false; 84 ll r = n-1,s = 0; 85 while(!(r&1)) 86 { 87 r = r >> 1; 88 s++; 89 } 90 for(ll i = 0;i < NUM;i++) 91 { 92 ll a = rand()%(n-1)+1; 93 if(check(a,n,r,s)) 94 return false; 95 } 96 return true; 97 } 98 99 // Pollard_rho算法 100 // 找出n的因子 101 ll Pollard_rho(ll n,ll c) 102 { 103 ll i = 1,j = 2,d,p; 104 ll x = rand()%n; 105 ll y = x; 106 while(true) 107 { 108 i++; 109 x = (mul_mod(x,x,n)+c)%n; 110 if(y == x) return n; 111 if(y > x) 112 p = y-x; 113 else 114 p = x-y; 115 d = gcd(p,n); 116 if(d != 1 && d != n) 117 return d; 118 if(i == j) 119 { 120 y = x; 121 j += j; 122 } 123 } 124 } 125 126 // 找出n的所有因子 127 void find(ll n) 128 { 129 if(Miller_Rabin(n)) 130 { 131 f[t++] = n; // 保存所有因子 132 return ; 133 } 134 ll p = n; 135 while(p >= n) 136 p = Pollard_rho(p,rand()%(n-1)+1); // p必定为合数,所以通过多次求解必定能得到答案 137 find(p); 138 find(n/p); 139 } 140 141 int main() 142 { 143 ios 144 #ifdef ONLINE_JUDGE 145 #else 146 freopen("in.txt","r",stdin); 147 // freopen("out.txt","w",stdout); 148 #endif 149 srand(time(NULL)); // 随机数设定种子 150 ll n; 151 cin >> n; 152 if(n == 1) 153 { 154 cout << "1" << endl; 155 return 0; 156 } 157 t = 0; 158 find(n); 159 sort(f,f+t); 160 map<ll,int> m; 161 for(int i = 0;i < t;i++) 162 m[f[i]]++; 163 map<ll,int>::iterator it; 164 ll ans = 1; 165 for(it = m.begin();it != m.end();it++) 166 { 167 int s = it->second; 168 ans *= 1+s; 169 } 170 cout << ans << endl; 171 172 fclose(stdin); 173 // fclose(stdout); 174 return 0; 175 }