分解
时间限制: 1000 ms 内存限制: 262144 KB
【考场TIME】
同样是春季体验营的一道题,DAY1 T2
这道题是比较迷的,当时理解错了题意,然后就GG了,打完之后回来检查才发现自己题读错了,当时真的很想砸电脑。。。
还有就是当时判-1的情况时,就错了,只判了1和2,结果后来才发现只要是2^k就会-1。然后结果就很尴尬,想来是每个测试点都有2^k,然后强势爆零。。。
【思路分析】
这里的关键点就是要只分解成n和n+1,所以分解的这个数是很均匀的所以我们就会很自然的想到用一个很迷的函数——pow( , )
我们只需要枚举最多60多次,就可以将一个1e18的数给分解了所以就很舒服。。。具体看代码吧,很好懂的。
【代码实现】
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 using namespace std; 5 long long ans[65][65]; 6 int num[65]; 7 long long temp[65]; 8 int main() 9 { 10 int T; 11 scanf("%d",&T); 12 while(T--) 13 { 14 long long n; 15 int tot=0; 16 scanf("%lld",&n); 17 long long m=n; 18 while(m%2==0) 19 m=m/2; 20 if(m==1||n==1) 21 { 22 printf("-1 "); 23 continue; 24 } 25 for(int j=62;j>=1;j--) 26 { 27 long long aa=(long long) pow(n,1.0/(long double)j); 28 if(aa==1) continue; 29 //printf("(%I64d)",aa); 30 long long bb=n; 31 int tt=0; 32 while(bb%aa==0) 33 { 34 bb=bb/aa; 35 tt++; 36 temp[tt]=aa; 37 } 38 int tt2=tt; 39 long long aa1=aa+1; 40 while(bb%aa1==0) 41 { 42 bb=bb/aa1; 43 tt++; 44 temp[tt]=aa1; 45 } 46 if(bb==1&&tt==j) 47 { 48 tot++; 49 num[tot]=tt; 50 for(int k=1;k<=tt2;k++) 51 ans[tot][k]=temp[k]; 52 for(int k=tt2+1;k<=tt;k++) 53 ans[tot][k]=temp[k]; 54 } 55 } 56 printf("%d ",tot); 57 for(int i=1;i<=tot;i++) 58 { 59 printf("%d ",num[i]); 60 for(int j=1;j<=num[i];j++) 61 printf("%lld ",ans[i][j]); 62 printf(" "); 63 } 64 } 65 return 0; 66 }