【2018校招筆試-京東=java開發】題目2 求冪
阿新 • • 發佈:2019-02-12
題目:
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);
}
}