题目链接:https://vjudge.net/problem/Gym-101612L
知识点: 数学
题目大意:
给一个数 (n(1 le n le 10^{18})),要求将 (n) 分解成 (a^{p}(a+1)^{q}),问有多少种分解方案。
解题思路:
如果 (n) 可以表示成 (2^{t}) 的形式,则有无限种分解方案,因为此时 (n) 可以分解成 (1^{p} imes 2^{t}) 的形式,其中 (p) 可以为任意整数。
接下来讨论有限种分解方案的情况。
(n=a^{p}(a+1)^{q}) 中的 (a) 近似等于 (lfloor ^{p+q} sqrt{n} floor = lfloor ^{r} sqrt{n} floor),其中 ((1 le r le log_2(n) le 64)),用求出的近似的 (a) 和 (a+1) 去尝试分解 (n) 即可。
AC代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 vector<vector<LL> > ans; 5 6 void solve(LL n,LL a){//试分解函数 7 vector<LL> ret; 8 while(n%a==0){ 9 ret.push_back(a); 10 n/=a; 11 } 12 while(n%(a+1)==0){ 13 ret.push_back(a+1); 14 n/=(a+1); 15 } 16 if(n==1){ 17 ans.push_back(ret); 18 } 19 } 20 int main(){ 21 freopen("little.in", "r", stdin); 22 freopen("little.out", "w", stdout); 23 LL n; 24 scanf("%lld",&n); 25 if((n&(n-1))==0){ //判断 n 是否是 1<<x 的形式的数 26 printf("-1 "); 27 return 0; 28 } 29 30 solve(n,n); 31 for(int s=1;s<=64;s++){ 32 LL r=(LL)pow(n,1.0/(double)s); 33 for(int j=-2;j<=2;j++){ 34 if(r+j>1) 35 solve(n,r+j); 36 } 37 } 38 sort(ans.begin(),ans.end()); 39 ans.erase(unique(ans.begin(),ans.end()),ans.end()); //去重 40 41 printf("%d ",ans.size()); 42 for(int i=0;i<ans.size();i++){ 43 printf("%d",ans[i].size()); 44 for(int j=0;j<ans[i].size();j++){ 45 printf(" %lld",ans[i][j]); 46 } 47 printf(" "); 48 } 49 return 0; 50 }