京东算法题---求幂

题目:

幂运算有一些有趣的性质: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);

	}

}



本人经验,仅供参考!


  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值