P2508 [HAOI2008]圆上的整点
题目描述
求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数。
输入输出格式
输入格式:
r
输出格式:
整点个数
输入输出样例
说明
n<=2000 000 000
/* 处理筛法: 筛素数筛到r<=2e9的话显然数组开不下 显然一个数有<=1个大于它的sqrt的素因子 所以我们筛小于等于sqrt(r)的范围内的素数 然后用筛出来的素数将n质因数分解后可能r!=1 这个时候的n就是n的那个大于sqrt(r)的素因子 处理计算: 如果prime[i]%4==3的话,prime[i]就是个素数,同时也是个高斯素数,对答案无影响 如果prime[i]%4==1,就记录prime[i]的指数tmp,让ans*=(tmp*2+1) 至于为什么这么做,自己看视频去。 https://www.bilibili.com/video/av12131743/ */ #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int N=4e4+5; bool flag[N]; int prime[N],cnt; inline void init() { for(int i=2;i<N;++i) { if(!flag[i]) prime[++cnt]=i; for(int j=1,k;j<=cnt&&(k=prime[j]*i)<N;++j) { flag[k]=1; if(i%prime[j]==0) break; } } } int n; int main() { init(); scanf("%d",&n); while((n&1)^1) n>>=1; int ans=1; for(int i=1,tmp=0;i<=cnt&&n!=1;++i) { if(n%prime[i]) continue; tmp=0; while(n%prime[i]==0) ++tmp,n/=prime[i]; if(prime[i]%4==1) ans*=(tmp<<1|1); } if(n>1&&n%4==1) ans*=3; cout<<(ans<<2); return 0; }
/* 处理筛法: 筛素数筛到r<=2e9的话显然数组开不下 显然一个数有<=1个大于它的sqrt的素因子 所以我们筛小于等于sqrt(r)的范围内的素数 然后用筛出来的素数将n质因数分解后可能r!=1 这个时候的n就是n的那个大于sqrt(r)的素因子 处理计算: 如果prime[i]%4==3的话,prime[i]就是个素数,同时也是个高斯素数,对答案无影响 如果prime[i]%4==1,就记录prime[i]的指数tmp,让ans*=(tmp*2+1) 至于为什么这么做,自己看视频去。 https://www.bilibili.com/video/av12131743/ */ #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int N=4e4+5; bool flag[N]; int prime[N],cnt; inline void init() { for(int i=2;i<N;++i) { if(!flag[i]) prime[++cnt]=i; for(int j=1,k;j<=cnt&&(k=prime[j]*i)<N;++j) { flag[k]=1; if(i%prime[j]==0) break; } } } int n; int main() { init(); scanf("%d",&n); while((n&1)^1) n>>=1; int ans=1; for(int i=1,tmp=0;i<=cnt&&n!=1;++i) { if(n%prime[i]) continue; tmp=0; while(n%prime[i]==0) ++tmp,n/=prime[i]; if(prime[i]%4==1) ans*=(tmp<<1|1); } if(n>1&&n%4==1) ans*=3; cout<<(ans<<2); return 0; }