P2508 [HAOI2008]圆上的整点

题目描述

求一个给定的圆(x^2+y^2=r^2),在圆周上有多少个点的坐标是整数。

输入输出格式

输入格式:

 

r

 

输出格式:

 

整点个数

 

输入输出样例

输入样例#1: 复制
4
输出样例#1: 复制
4

说明

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

 

posted @ 2018-09-13 10:49  whymhe  阅读(330)  评论(0编辑  收藏  举报