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} 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 }

  

“这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
原文地址:https://www.cnblogs.com/Blogggggg/p/8975103.html