Loading

German Collegiate Programming Contest 2015 F. Divisions

描述

传送门: 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 }

 

posted @ 2021-01-20 17:35  Yiduuannng  阅读(77)  评论(0)    收藏  举报