1. 程式人生 > >【2018校招筆試-京東=java開發】題目2 求冪

【2018校招筆試-京東=java開發】題目2 求冪

題目:

a^b = c^d,且1<=a,b,c,d<=n
在給定n的情況下,求滿足上述式子的個數。

思路:

我們考慮去列舉n範圍內的所有i,然後處理出i的冪那些數。
考慮對於i ^ x, 我們需要計算滿足 (i ^ x) ^ c = (i ^ y) ^ d的數量,其中i ^ x, i ^ y <= n. 這些我們可以通過預處理出來。
然後對於(i ^ x) ^ c = (i ^ y) ^ d 其實意味著x c = y d, 意味著(x / y) = (d / c), 其中x, y我們可以在預處理之後枚舉出來,於是我們就可以藉此計算出n範圍內有多少不同這種c和d去滿足等式。
其實就等於 n / max(x / gcd(x, y), y / gcd(x, y)),然後都累加進答案。gcd()表示最大公約數。
中間可能產生重複列舉,我們用一個set或者hash容器標記一下就好。

以上列舉對於2~sqrt(n)。最後對於大於sqrt(n)的部分,每個的貢獻都是n。

程式碼:

作者:牛妹
連結:https://www.nowcoder.com/discuss/38889?type=0&order=3&pos=6&page=1
來源:牛客網

import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
 
public class Main {
 
  public final static long MOD = 1000000000 + 7;
 
  public static
int max(int a, int b){     return (a>b) ? a : b;   }     public static long gcd(long a,long b){     return (a % b == 0) ? b : gcd(b,a%b);   }     public static void main(String[] args) {     Scanner in = new Scanner(System.in);     long n = in.nextInt();     long ans = (long)1*n*(n*2-1) % MOD;     Set<Integer> set
  = new HashSet<>();     for (int i = 2; i*i <= n; i++){       if ( set.contains(i)) continue;       long tmp = i;       int cnt = 0;         while(tmp <= n) {         set.add((int)tmp);         tmp = tmp * i;         cnt++;       }         for(int k = 1; k <= cnt; k++) {         for(int j = k + 1; j <= cnt; j++) {           ans = (ans + n / (j / gcd(k, j) ) * (long)2 ) % MOD;         }       }       }       System.out.println(ans);   } }