京東演算法題---求冪
題目:
冪運算有一些有趣的性質: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的個數,
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); } }
本人經驗,僅供參考!