zoukankan      html  css  js  c++  java
  • 牛客算法周周练5

    链接:https://ac.nowcoder.com/acm/contest/5556/B
    来源:牛客网

    时间限制:C/C++ 1秒,其他语言2秒
    空间限制:C/C++ 32768K,其他语言65536K
    64bit IO Format: %lld

    题目描述

    东东对幂运算很感兴趣,在学习的过程中东东发现了一些有趣的性质: 9^3 = 27^2, 2^10 = 32^2
    东东对这个性质充满了好奇,东东现在给出一个整数n,希望你能帮助他求出满足 a^b = c^d(1 ≤ a,b,c,d ≤ n)的式子有多少个。
    例如当n = 2:
    1^1=1^1
    1^1=1^2
    1^2=1^1
    1^2=1^2
    2^1=2^1
    2^2=2^2
    一共有6个满足要求的式子

    输入描述:

    输入包括一个整数n(1 ≤ n ≤ 10^6)

    输出描述:

    输出一个整数,表示满足要求的式子个数。因为答案可能很大,输出对1000000007求模的结果

    示例1

    输入

    2

    输出

    6

    题解from:https://www.jianshu.com/p/41fbd79255bd

    从易到难分三种情况分析:

    1. 以1为底的式子
    2. 1以外的数为底的式子
    3. 幂关系

    问题

    1. (x / y) = (d / c)怎么来的?
      9^{3} = 27^{2},2^{10} = 32^2分析
      9^{3} = 27^{2}Rightarrow {3^2}^{3} = {3^3}^{2} Rightarrow 3^{2 	imes 3} = 3^{3 	imes 2} = 3^6
      2^{10} = 32^2 Rightarrow {2^1}^{10} = {2^5}^2 Rightarrow 2 ^{1 	imes 10} = 2 ^{5 	imes 2} = 2^{10}
      i表示底数,用x,y,b,c表示指数,那么存在关系(i ^ x) ^ c = (i ^ y) ^d。根据幂的指数乘方运算法则x * c = y * d, 问题转换为找到满足(x / y) = (d / c)的个数。
    2. 为什么要使用(x/y)=(d/y)?
      因为比较容易计算,d/cx/y经过约分后,最简分数一样。如果x/y是最简分数,那么d/cx/y的倍数。
    3. x,y如何确定?
      x,yi的幂值,可以通过枚举i获得。i^x≤ni^y≤n,因此可以遍历i的各个幂值。
    4. 为什么要y/gcd(x,y)?
      因为x/y要约分,使x/y成为最简分数。y/gcd(x,y)是约分后的分母,同样x/gcd(x,y)是约分后的分子。
    5. 为什么n要除以y/gcd(x,y)?
      x/y经过约分后,成为最简分数。y/gcd(x,y)是最简分数的分母,n/(y/gcd(x,y))表示n内有多少个最简分母的倍数,也就是有多少组cd
    6. 为什么*2?因为等号左右交换位置也算一种情况,所以*2


     1 #include <bits/stdc++.h>
     2 typedef long long LL;
     3 #define pb push_back
     4 const int INF = 0x3f3f3f3f;
     5 const double eps = 1e-8;
     6 const int mod = 1e9+7;
     7 const int maxn = 1e5+10;
     8 using namespace std;
     9 
    10 set<int> st;
    11 
    12 int gcd(int a, int b)
    13 {
    14     return b?gcd(b,a%b):a;
    15 }
    16 
    17 int main()
    18 {
    19     #ifdef DEBUG
    20     freopen("sample.txt","r",stdin); //freopen("data.out", "w", stdout);
    21     #endif
    22     
    23     int n;
    24     scanf("%d",&n);
    25     LL ans = (1LL*n*(2*n-1))%mod;
    26     for(int i=2;i*i<=n;i++)
    27     {
    28         if(st.find(i)!=st.end()) continue; //如果已经存在则跳过
    29         LL t=i;
    30         int num=0;
    31         while(t<=n) //求关于i的<=n的最大幂
    32         {
    33             st.insert(t);
    34             t*=i;
    35             num++;
    36         }
    37         for(int x=1;x<=num;x++) //遍历统计到的幂
    38         {
    39             for(int y=x+1;y<=num;y++)
    40             {
    41                 ans=(ans+n/(y/gcd(x,y))*2LL)%mod;
    42             }
    43         }
    44     }
    45     printf("%lld
    ",ans);
    46     
    47     return 0;
    48 }

    -

  • 相关阅读:
    北邮《数据库原理与应用》应用阶段作业二带答案
    指针(字符串排序)
    Mysql—二进制日志(binlog)
    Mysql—日志文件系统
    7zip批量压缩,并批量改.jar
    解决:Windows 强制升级为8.1之后 Mysql连接不上, VisualSVN Server无服务
    推荐一个很好的博客
    c/c++ 继承与多态 继承时如何改变个别成员的访问属性
    c/c++ 继承与多态 友元与继承
    c/c++ 继承与多态 由子类向父类的转换规则
  • 原文地址:https://www.cnblogs.com/jiamian/p/12853276.html
Copyright © 2011-2022 走看看