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