后来看了一下题解里的视频,想了想,感觉很有道理,就开始了第二次奋斗历程。
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; long long n; long long ans=1,sum; int p[1000001],c[1000001]; int main(){ scanf("%lld",&n); int m=n*n; for(int i=2;i<=n;i++) if(m%i==0){ p[++sum]=i; while(m%i==0) m/=i,c[sum]++; } if(m>1){ p[++sum]=m;c[sum]++; } for(int i=1;i<=sum;i++) cout<<p[i]<<" "<<c[i]<<endl; for(int i=1;i<=sum;i++){ if(p[i]%2==0) continue; else if(p[i]%4==1) ans*=c[i]; else if(p[i]%4==3&&c[i]%2!=0) ans=0; } if(ans==0){ printf("0 ");return 0; } else if(ans==1){ printf("4 ");return 0; } else cout<<ans*4+4; }
结果发现,调试忘记注释了。。。
只有某个奇怪的点得分了。。。
然后我就以为我把调试注释以后,就能AC4个点。然并卵,还是20分。
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; long long n; long long ans=1,sum; int p[10000001],c[10000001]; int main(){ scanf("%lld",&n); int m=n*n; for(long long i=2;i<=n;i++) if(m%i==0){ p[++sum]=i; while(m%i==0) m/=i,c[sum]++; } if(m>1){ p[++sum]=m;c[sum]++; } // for(int i=1;i<=sum;i++) cout<<p[i]<<" "<<c[i]<<endl; for(int i=1;i<=sum;i++){ if(p[i]%2==0) continue; else if(p[i]%4==1) ans*=c[i]; else if(p[i]%4==3&&c[i]%2!=0) ans=0; } if(ans==0){ printf("0 ");return 0; } else if(ans==1){ printf("4 ");return 0; } else cout<<ans*4+4; }
最后,终于胜利了!!
这是对上一个代码的优化。
首先 先把n的因数中的2都消去,因为2对答案并没有贡献。
其次 一个数 n*n=n^2 可以因式分解n^2=p1a1*2*p2a1*2*p3a3*2*......
所以,因式分解后的质数,如果模4后余1那ans=ans*(ai*2+1);最后ans*4。
还有自身是%4=1的质数的情况特判一下。ans=ans*(1*2+1)=ans*3;
然后输出就好了。
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int ans=4; int n,sum=1; int main(){ scanf("%d",&n); while((n&1)^1) n>>=1; while(sum*sum<=n) sum++; for(int i=2;i<=sum;i++) if(n%i==0){ int tmp=0; while(n%i==0){ n/=i;tmp+=2; } if(i%4==1) ans=ans*(tmp+1); } if(n>1&&n%4==1) ans*=3; printf("%d",ans); }