题目:
幂运算有一些有趣的性质: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^5)
输出:
满足条件的式子的个数ans
思路: 首先,在不考虑a,b,c,d之间存在幂关系的情况下,可以发现满足条件的式子的个数有一个通式 n*(2*n-1),得到的方法为先将以1为底的式子作为特例,那么形式为1^n的式子组成满足条件的等式的个数为n^2,然后再考虑以除1以外的数为底的式子,总共有n*(n-1)个式子满足条件,那么综上所述,在不考虑幂关系的情况下,满足题目条件的式子的个数为n*(2*n-1);然后再考虑有幂关系的情况,假设n>32,以2^10 = 32^2为例,可以看成 (2^1)^10 = (2^5)^2,那么对于幂的指数可以发现1*10 = 5*2,由此,对于i(1≤i≤n)存在幂关系 (i^x)^c = (i^y)^d ,意味着x*c = y*d,即 x/y = c/d,那么问题就转换为找到满足x/y = c/d的个数,对于x和y我们可以通过如下方式枚举出来:由于i^x≤n,i^y≤n,因此可以遍历i的各个幂值,为了防止重复统计,可以使用一个HashSet来存放已经统计过的数,使用变量cnt来控制x和y的范围,然后遍历x和y,通过用x,y中较大的数除以x和y的最大公约数,相当于进行了约分,然后用n除以这个约分后的较大的数则可以得到在n以内最多有多少满足的c和d,最后的结果要乘以2,因为等号两边是可以互换称谓一种可能,最后将两种情况的数量和相加则为最后的结果。 具体代码如下:
import java.util.*;
public class JingDong
{
public final static long MOD = 1000000007;
public static long gdc(long a,long b) //求a和b的最大公约数
{
return (a%b==0)?b:gdc(b,a%b);
}
public static void main(String[] args)
{
Scanner s = new Scanner(System.in);
long n = s.nextLong();
long ans = (long)n*(2*n-1) % MOD; //算出不包含幂的总数
Set<Integer> set = new HashSet<>();
for(int i=2;i*i<n;i++)
{
if(set.contains(i)) //已经遍历过,则跳过
continue;
long temp = i;
long cnt = 0;
while(temp<=n) //算出x,y的值域,最大值cnt
{
set.add((int)temp);
temp = temp*i;
cnt++;
}
for(int k=1;k<=cnt;k++) //遍历x和y
{
for(int j=k+1;j<=cnt;j++)
{
ans = (ans + n/(j/gdc(k,j))*(long)2) % MOD;
}
}
}
System.out.println(ans);
}
}
本人经验,仅供参考!