zoukankan      html  css  js  c++  java
  • 数论杂题

    ①:给定正整数N,求满足a+b≤N,a+b|a*b,数对(a,b)的个数,N≤1e14.

    我们设d = gcd(a,b).那么a = a'*d,b = b'*d,易得gcd(a',b') == 1.

    将a = a'*d与b = b'*d代入a+b | a*b,易得(a'+b' ) | a'b'd.

    显然我们得(a'+b') 不被 a'b'整除,那么(a' + b') | d.

    我们设a' + b' = k, k * d = n ,t*k = d,那么k ∈[ 2,sqrt(N)].

    那对于一个给定的k,它的合法个数呢?

    (a'+b')*d = k * k * t ≤ n,那么t  ≤ N/(k*k),注意k是不变的,t 的范围即k在N范围内的合法个数.

    那对于一个给定k,合法(a',b')数对的个数呢?应为k = a'+b',gcd(a'+b',a') = 1,那么ans显然是φ(k).

    ans = (n/k*k)*φ(k),k∈[2.sqrt(N)],O(sqrt(N))

     

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    #define e exit(0)
    #define re register
    #define LL long long
    const LL maxn = 1e7+1;
    LL n,t,ans;
    int cnt,prime[maxn],vis[maxn],Ins[maxn];
    int main()
    {
        scanf("%lld",&n);
        LL t = sqrt(n);
        Ins[1] = 1;
        for(re int i=2;i<=t;++i){    
            if(!vis[i]){
                prime[++cnt] = i;
                Ins[i] = i-1;
            }
            for(re int j=1;j<=cnt;++j){
                if(i*prime[j] > t)
                    break;
                vis[i*prime[j]] = 1;
                if(i%prime[j] == 0){
                    Ins[i*prime[j]] = Ins[i]*prime[j];
                    break;
                }
                else Ins[i*prime[j]] = Ins[i]*Ins[prime[j]];
            }
        }
        for(re LL k=2;k<=t;++k)
            ans += (LL)(n/(k*k))*(LL)Ins[k];
        printf("%lld",ans);
        return 0;
    }

     

     

  • 相关阅读:
    C#中如何求时间间隔?
    Ilist<T> 转换成 DataSet
    EditPlus 快捷键
    Array和ArrayList的异同点
    sql server 查询数据库中有多少个表
    jquery + Css 模式对话框
    paddingtop、margintop和top的区别
    JQuery之ContextMenu(右键菜单)
    关于TextBox的Enable与ReadOnly属性
    AjaxToollit 3.5 使用整理
  • 原文地址:https://www.cnblogs.com/xqysckt/p/11809290.html
Copyright © 2011-2022 走看看