Andrew has just made a breakthrough in group theory: he realized that he can classify all finite Abelian groups (not much of a breakthrough, indeed). Given
n, how many Abelian groups with
n elements exist up to isomorphism? To help you solve this problem we provide some definitions and theorems from basic algebra (most are cited from Wikipedia). An abelian group is a set,
A, together with an operation '·' that combines any two elements
a and
b to form another element denoted
a ·
b. The symbol '·' is a general placeholder for a concretely given operation. To qualify as an abelian group, the set and operation, (
A, ·), must satisfy five requirements known as the abelian group axioms:
- Closure: for all a, b in A, the result of the operation a · b is also in A.
- Associativity: for all a, b and c in A, the equation (a · b) · c = a · (b · c) holds.
- Identity element: there exists an element e in A, such that for all elements a in A, the equation e · a = a · e = a holds.
- Inverse element: for each a in A, there exists an element b in A such that a · b = b · a = e, where e is the identity element.
- Commutativity: for all a, b in A, a · b = b · a.
Input
First and only line of the input file contains an integer
n, 1 ≤
n ≤ 10
12.
Output
In the only line of the output file write the number of abelian groups with
n elements.
Sample Input
Example(s)
sample input | sample output |
5 | 1 |
数学题:
http://mathworld.wolfram.com/AbelianGroup.html
英文慢慢看吧。。。看完这个AC好爽!!!!!!!
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <queue>
#include <string>
using namespace std;
const int maxn = 1000000+10;
vector<long long> prime;
long long dp[200][200];
long long n;
bool vis[maxn];
void getPrime(){
memset(vis,0,sizeof(vis));
for(long long i = 2; i < maxn; i++){
if(!vis[i]){
for(long long j = i*i; j < maxn; j+=i){
vis[j] = 1;
}
}
}
for(int i = 2; i < maxn; i++){
if(!vis[i])
prime.push_back(i);
}
}
void init(){
for(int i = 1; i < 100; i++){
for(int j = 1; j < 100; j++){
if(i==1||j==1){
dp[i][j] = 1;
}
else if(i<j){
dp[i][j] = dp[i][i];
}
else if(i==j){
dp[i][j] = dp[i][j-1]+1;
}else{
dp[i][j] = dp[i][j-1]+dp[i-j][j];
}
}
}
}
void solve(){
int i=0;
long long ans = 1;
while(n!=1&&i<prime.size()){
long long t = 0;
if(n%prime[i]==0){
while(n%prime[i]==0){
t++;
n/=prime[i];
}
}
else i++;
if(t!=0)
ans *= dp[t][t];
}
if(ans == 0)
ans = 1;
cout<<ans<<endl;
}
int main(){
getPrime();
init();
while(~scanf("%lld",&n)){
solve();
}
return 0;
}