• 【BZOJ 1041】[HAOI2008]圆上的整点


    【题目链接】:http://www.lydsy.com/JudgeOnline/problem.php?id=1041

    【题意】

    【题解】

    由圆的方程可得
    X^2+Y^2=R^2
    X^2=R^2-Y^2
    X^2=(R+Y)(R-Y)
    这里令
    D = gcd(R+Y,R-Y);

    gcd((R+Y)/D,(R-Y)/D)==1
    那么
    令R+Y=D*A,R-Y=D*B
    则X^2=D*A*D*B
    这里A!=B
    因为X^2是完全平方数,而A!=B则必有A和B分别是完全平方数
    设A=u^2,B=v^2

    X^2=D*u^2*D*v^2
    且u!=v
    且u>v
    可得
    Y=D*(v^2-u^2)/2
    X=D*u*v
    R=D*(u^2+v^2)/2
    这里处理出2*R的所有因子D
    对于每一个D
    枚举v
    因为u>v
    所以v枚举的上界是sqrt(R/d)就可以了
    (具体的上界取sqrt((R+1)/d),不能取等号,不然会出现Y为0的情况(即U=V).而那种情况我们最后结果会加上去;
    即4个坐标轴上的点.)
    对于每个v求出u_2
    然后看看u_2是不是完全平方数,以及u_2和v_2是不是互质的,是就递增答案;
    这样能求出一个象限的,然后乘4再加上坐标轴上的4个点就好了;

    【完整代码】

    #include <bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    #define rei(x) scanf("%d",&x)
    #define rel(x) scanf("%lld",&x)
    #define ref(x) scanf("%lf",&x)
    
    typedef pair<int, int> pii;
    typedef pair<LL, LL> pll;
    
    const int dx[9] = { 0,1,-1,0,0,-1,-1,1,1 };
    const int dy[9] = { 0,0,0,-1,1,-1,1,-1,1 };
    const double pi = acos(-1.0);
    const int N = 110;
    
    LL r,ans = 0;
    vector <LL> v;
    
    void in()
    {
        rel(r);
    }
    
    void get_divisor(LL x)
    {
        LL i;
        for (i = 1; i*i < x; i++)
            if (x%i == 0)
                v.push_back(i), v.push_back(x / i);
        if (i*i == x)
            v.push_back(i);
    }
    
    bool is_sqr(LL x)
    {
        double t = sqrt((double)x);
        if (fabs(floor(t + 1e-7) - t) < 1e-7)
            return true;
        return false;
    }
    
    LL gcd(LL a, LL b)
    {
        if (b == 0)
            return a;
        else
            return gcd(b, a%b);
    }
    
    void get_ans()
    {
        LL V;
        int len = v.size();
        rep1(i, 0, len - 1)
        {
            LL d = v[i];
            for (V = 1; V*V < (r + 1) / d; V++)
            {
                LL U_2 = 2 * r / d - V*V;
                if (is_sqr(U_2))
                    if (gcd(V*V, U_2) == 1)
                    {
                        ans++;
                    }
            }
        }
    }
    
    void o()
    {
        printf("%lld
    ", ans*4+4);
    }
    
    int main()
    {
        //freopen("F:\rush.txt", "r", stdin);
        in();
        if (r == 1)
        {
            puts("4");
            return 0;
        }
        get_divisor(r << 1);
        get_ans();
        o();
        //printf("
    %.2lf sec 
    ", (double)clock() / CLOCKS_PER_SEC);
        return 0;
    }
    
  • 相关阅读:
    今日成长笔记2016-11-18
    牛人博客
    c 、c++、java区别
    Java开发中的23种设计模式详解
    JAVA编程规范
    设计及编码质量改进之降低耦合度
    加密
    敏捷开发之Scrum扫盲篇
    RPC
    李洪强iOS开发Swift篇—04_运算符
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626520.html
Copyright © 2020-2023  润新知