1. 程式人生 > >京東演算法題---求冪

京東演算法題---求冪

題目:

冪運算有一些有趣的性質: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);

	}

}


本人經驗,僅供參考!