Gym101612L Little Difference

题目链接: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} \times 2^{t}\) 的形式,其中 \(p\) 可以为任意整数。

  接下来讨论有限种分解方案的情况。

  \(n=a^{p}(a+1)^{q}\) 中的 \(a\) 近似等于 \(\lfloor ^{p+q} \sqrt{n} \rfloor = \lfloor ^{r} \sqrt{n} \rfloor\),其中 \((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\n");
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\n",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("\n");
48     }
49     return 0;
50 }

 

  

posted @ 2018-04-30 23:10  Blogggggg  阅读(166)  评论(0编辑  收藏  举报