• 牛客P21578 思维,数论


    题意:

    给定 n n n,求有多少四元组 ( a , b , c , d ) (a,b,c,d) (a,b,c,d)满足 a b = c d a^b=c^d ab=cd

    Solution:

    从唯一分解看,幂 b , d b,d b,d只改变质因数的幂,而不改变质因数的种数,因此,要满足题意, a , c a,c a,c一定存在结构一样的部分,设为 x x x,那么
    a = x k 1 c = x k 2 a=x^{k_{1}}\\ c=x^{k_{2}} a=xk1c=xk2

    • x = 1 x=1 x=1 b , d b,d b,d不一定一样,且都任意取值,方案数为 n 2 n^2 n2,此时为 a = c = 1 a=c=1 a=c=1

    • a = c ≠ 1 a=c\neq1 a=c=1时, a = c ∈ [ 2 , n ] a=c\in[2,n] a=c[2,n] b = d ∈ [ 1 , n ] b=d\in[1,n] b=d[1,n],方案数为 n ( n − 1 ) n(n-1) n(n1)

    • 下面只需要考虑 a ≠ c a\neq c a=c的情况

      当我们知道同样部分 x x x的时候,我们很容易可以知道以这个数为最小结构的数有多少,而我们只需要枚举一个最小的 x x x,就可以统计所有以 x x x为最小结构的数,他们分别是
      x , x 2 , x 3 , . . . . x,x^2,x^3,.... x,x2,x3,....
      此时只需要找出序列长度大于 2 2 2 x x x,即 x 2 ≤ n ⇒ x ≤ n x^2\leq n\Rightarrow x\leq\sqrt{n} x2nxn ,我们用 O ( n ) O(\sqrt{n}) O(n )枚举 x x x,只需要找出最大的 i i i满足 x i ≤ n x^i\leq n xin,即可找出这些数,那么 a , c a,c a,c一定出现在这些数之中,原题要满足
      x b k 1 = x d k 2 ⇒ b k 1 = d k 2 x^{bk_{1}}=x^{dk_{2}}\Rightarrow bk_{1}=dk_{2} xbk1=xdk2bk1=dk2

      由于 n ≤ 1 0 9 n\leq 10^9 n109,因为 2 32 > 1 0 9 2^{32}>10^9 232>109,于是 i ≤ 32 i\leq 32 i32,所以考虑枚举 k 1 , k 2 k_{1},k_{2} k1,k2,由于 a ≠ c a\neq c a=c,即 k 1 ≠ k 2 k_{1}\neq k_{2} k1=k2,此时方程解的组数就是方案数,先化简方程至 g c d ( k 1 , k 2 ) = 1 gcd(k_{1},k_{2})=1 gcd(k1,k2)=1,即解
      b d = k 2 k 1 \frac{b}{d}=\frac{k_{2}}{k_{1}} db=k1k2
      b = k 2 x ≤ n , d = k 1 x ≤ n b=k_{2}x\leq n,d=k_{1}x \leq n b=k2xn,d=k1xn,有 x ≤ m i n { n k 1 , n k 2 } x\leq min\{\frac{n}{k_{1}},\frac{n}{k_{2}}\} xmin{k1n,k2n}

      如果不化简,这个 x x x可能不是最大的

      最后,这个序列的元素的都用最小的 x x x统计了,所以 x x x的其他幂需要跳过,数组记录即可

    // #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    using namespace std;
    
    using ll=long long;
    const int N=1e5+5,inf=0x3fffffff;
    const long long INF=0x3fffffffffffffff,mod=1e9+7;
    
    ll n,ans;
    bool vis[N];
    
    int main()
    {
        cin>>n; ans=(1ll*n*n%mod+1ll*n*(n-1)%mod)%mod;
        int limit=sqrt(n);
        for(int i=2;i<=limit;i++)
        {
            if(vis[i]) continue;
            ll max1=1,now=i;
            while(now*i<=n) max1++,now*=i;
            now=i;
            for(int j=1;j<=max1;j++)
            {
                if(now<=limit) vis[now]=true;
                for(int k=1;k<=max1;k++)
                    if(j!=k) ans=(ans+n/max(j/__gcd(j,k),k/__gcd(j,k)))%mod;
                now*=i;
            }
        }
        cout<<ans;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
  • 相关阅读:
    【SSM】SpringMVC系列——SpringMVC注解式开发1
    List 去重的几种方法
    el-select的某一项选中后显示id
    Spring-ImportSelector接口功能介绍
    汽车一键启动点火开关按键一键启动按钮型号规格
    shiro-反序列化漏洞
    AI助力剧本创作:如何5分钟内构思出热门短剧大纲
    RabbitMQ之消息模式简单易懂,超详细分享~~~
    学习nginx,这一篇就够了
    数据库概述01
  • 原文地址:https://blog.csdn.net/stdforces/article/details/127760499