diff --git a/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/README.md b/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/README.md
index 028ce23a4b119..12be054cfe9aa 100644
--- a/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/README.md	
+++ b/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/README.md	
@@ -80,24 +80,244 @@
 
 ## 解法
 
-### 方法一
+### 方法一:二分查找 + 容斥原理
+
+我们可以将题目转化为:找到最小的正整数 $x$,使得小于等于 $x$ 的且满足条件的数的个数恰好为 $k$ 个。如果 $x$ 满足条件,那么对任意 $x' > x$ 的 $x'$ 也满足条件,这存在单调性,因此我们可以使用二分查找,找到最小的满足条件的 $x$。
+
+我们定义一个函数 `check(x)`,用来判断小于等于 $x$ 的且满足条件的数的个数是否大于等于 $k$。我们需要计算有多少个数可以由 $coins$ 中的数组合得到。
+
+假设 $coins$ 为 $[a, b]$,根据容斥原理,小于等于 $x$ 的满足条件的数的个数为:
+
+$$
+\left\lfloor \frac{x}{a} \right\rfloor + \left\lfloor \frac{x}{b} \right\rfloor - \left\lfloor \frac{x}{lcm(a, b)} \right\rfloor
+$$
+
+如果 $coins$ 为 $[a, b, c]$,小于等于 $x$ 的满足条件的数的个数为:
+
+$$
+\left\lfloor \frac{x}{a} \right\rfloor + \left\lfloor \frac{x}{b} \right\rfloor + \left\lfloor \frac{x}{c} \right\rfloor - \left\lfloor \frac{x}{lcm(a, b)} \right\rfloor - \left\lfloor \frac{x}{lcm(a, c)} \right\rfloor - \left\lfloor \frac{x}{lcm(b, c)} \right\rfloor + \left\lfloor \frac{x}{lcm(a, b, c)} \right\rfloor
+$$
+
+可以看到,我们需要累加所有任意奇数个数的情况,减去所有任意偶数个数的情况。
+
+由于 $n \leq 15$,我们可以使用二进制枚举的方式,枚举所有的子集,计算满足条件的数的个数,我们记为 $cnt$。如果 $cnt \geq k$,那么我们需要找到最小的 $x$,使得 $check(x)$ 为真。
+
+在二分查找开始时,我们定义二分查找的左边界 $l=1$,右边界 $r={10}^{11}$,然后我们不断地将中间值 $mid$ 代入 `check` 函数中,如果 `check(mid)` 为真,那么我们将右边界 $r$ 更新为 $mid$,否则我们将左边界 $l$ 更新为 $mid+1$。最终返回 $l$。
+
+时间复杂度 $O(n \times 2^n \times \log (k \times M))$,其中 $n$ 是数组 $coins$ 的长度,而 $M$ 是数组 $coins$ 中的最大值。
 
 <!-- tabs:start -->
 
 ```python
-
+class Solution:
+    def findKthSmallest(self, coins: List[int], k: int) -> int:
+        def check(mx: int) -> bool:
+            cnt = 0
+            for i in range(1, 1 << len(coins)):
+                v = 1
+                for j, x in enumerate(coins):
+                    if i >> j & 1:
+                        v = lcm(v, x)
+                        if v > mx:
+                            break
+                m = i.bit_count()
+                if m & 1:
+                    cnt += mx // v
+                else:
+                    cnt -= mx // v
+            return cnt >= k
+
+        return bisect_left(range(10**11), True, key=check)
 ```
 
 ```java
-
+class Solution {
+    private int[] coins;
+    private int k;
+
+    public long findKthSmallest(int[] coins, int k) {
+        this.coins = coins;
+        this.k = k;
+        long l = 1, r = (long) 1e11;
+        while (l < r) {
+            long mid = (l + r) >> 1;
+            if (check(mid)) {
+                r = mid;
+            } else {
+                l = mid + 1;
+            }
+        }
+        return l;
+    }
+
+    private boolean check(long mx) {
+        long cnt = 0;
+        int n = coins.length;
+        for (int i = 1; i < 1 << n; ++i) {
+            long v = 1;
+            for (int j = 0; j < n; ++j) {
+                if ((i >> j & 1) == 1) {
+                    v = lcm(v, coins[j]);
+                    if (v > mx) {
+                        break;
+                    }
+                }
+            }
+            int m = Integer.bitCount(i);
+            if (m % 2 == 1) {
+                cnt += mx / v;
+            } else {
+                cnt -= mx / v;
+            }
+        }
+        return cnt >= k;
+    }
+
+    private long lcm(long a, long b) {
+        return a * b / gcd(a, b);
+    }
+
+    private long gcd(long a, long b) {
+        return b == 0 ? a : gcd(b, a % b);
+    }
+}
 ```
 
 ```cpp
-
+class Solution {
+public:
+    long long findKthSmallest(vector<int>& coins, int k) {
+        using ll = long long;
+        ll l = 1, r = 1e11;
+        int n = coins.size();
+
+        auto check = [&](ll mx) {
+            ll cnt = 0;
+            for (int i = 1; i < 1 << n; ++i) {
+                ll v = 1;
+                for (int j = 0; j < n; ++j) {
+                    if (i >> j & 1) {
+                        v = lcm(v, coins[j]);
+                        if (v > mx) {
+                            break;
+                        }
+                    }
+                }
+                int m = __builtin_popcount(i);
+                if (m & 1) {
+                    cnt += mx / v;
+                } else {
+                    cnt -= mx / v;
+                }
+            }
+            return cnt >= k;
+        };
+
+        while (l < r) {
+            ll mid = (l + r) >> 1;
+            if (check(mid)) {
+                r = mid;
+            } else {
+                l = mid + 1;
+            }
+        }
+        return l;
+    }
+};
 ```
 
 ```go
+func findKthSmallest(coins []int, k int) int64 {
+	var r int = 1e11
+	n := len(coins)
+	ans := sort.Search(r, func(mx int) bool {
+		cnt := 0
+		for i := 1; i < 1<<n; i++ {
+			v := 1
+			for j, x := range coins {
+				if i>>j&1 == 1 {
+					v = lcm(v, x)
+					if v > mx {
+						break
+					}
+				}
+			}
+			m := bits.OnesCount(uint(i))
+			if m%2 == 1 {
+				cnt += mx / v
+			} else {
+				cnt -= mx / v
+			}
+		}
+		return cnt >= k
+	})
+	return int64(ans)
+}
+
+func gcd(a, b int) int {
+	if b == 0 {
+		return a
+	}
+	return gcd(b, a%b)
+}
+
+func lcm(a, b int) int {
+	return a * b / gcd(a, b)
+}
+```
 
+```ts
+function findKthSmallest(coins: number[], k: number): number {
+    let [l, r] = [1n, BigInt(1e11)];
+    const n = coins.length;
+    const check = (mx: bigint): boolean => {
+        let cnt = 0n;
+        for (let i = 1; i < 1 << n; ++i) {
+            let v = 1n;
+            for (let j = 0; j < n; ++j) {
+                if ((i >> j) & 1) {
+                    v = lcm(v, BigInt(coins[j]));
+                    if (v > mx) {
+                        break;
+                    }
+                }
+            }
+            const m = bitCount(i);
+            if (m & 1) {
+                cnt += mx / v;
+            } else {
+                cnt -= mx / v;
+            }
+        }
+        return cnt >= BigInt(k);
+    };
+    while (l < r) {
+        const mid = (l + r) >> 1n;
+        if (check(mid)) {
+            r = mid;
+        } else {
+            l = mid + 1n;
+        }
+    }
+    return Number(l);
+}
+
+function gcd(a: bigint, b: bigint): bigint {
+    return b === 0n ? a : gcd(b, a % b);
+}
+
+function lcm(a: bigint, b: bigint): bigint {
+    return (a * b) / gcd(a, b);
+}
+
+function bitCount(i: number): number {
+    i = i - ((i >>> 1) & 0x55555555);
+    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
+    i = (i + (i >>> 4)) & 0x0f0f0f0f;
+    i = i + (i >>> 8);
+    i = i + (i >>> 16);
+    return i & 0x3f;
+}
 ```
 
 <!-- tabs:end -->
diff --git a/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/README_EN.md b/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/README_EN.md
index f981614bafcf3..26b79079a82ed 100644
--- a/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/README_EN.md	
+++ b/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/README_EN.md	
@@ -82,24 +82,244 @@ All of the coins combined produce: 2, 4, 5, 6, 8, 10, <u><strong>12</strong></u>
 
 ## Solutions
 
-### Solution 1
+### Solution 1: Binary Search + Inclusion-Exclusion Principle
+
+We can transform the problem into: find the smallest positive integer $x$ such that the number of numbers less than or equal to $x$ and satisfying the condition is exactly $k$. If $x$ satisfies the condition, then for any $x' > x$, $x'$ also satisfies the condition. This shows monotonicity, so we can use binary search to find the smallest $x$ that satisfies the condition.
+
+We define a function `check(x)` to determine whether the number of numbers less than or equal to $x$ and satisfying the condition is greater than or equal to $k$. We need to calculate how many numbers can be obtained from the array $coins$.
+
+Suppose $coins = [a, b]$, according to the inclusion-exclusion principle, the number of numbers less than or equal to $x$ and satisfying the condition is:
+
+$$
+\left\lfloor \frac{x}{a} \right\rfloor + \left\lfloor \frac{x}{b} \right\rfloor - \left\lfloor \frac{x}{lcm(a, b)} \right\rfloor
+$$
+
+If $coins = [a, b, c]$, the number of numbers less than or equal to $x$ and satisfying the condition is:
+
+$$
+\left\lfloor \frac{x}{a} \right\rfloor + \left\lfloor \frac{x}{b} \right\rfloor + \left\lfloor \frac{x}{c} \right\rfloor - \left\lfloor \frac{x}{lcm(a, b)} \right\rfloor - \left\lfloor \frac{x}{lcm(a, c)} \right\rfloor - \left\lfloor \frac{x}{lcm(b, c)} \right\rfloor + \left\lfloor \frac{x}{lcm(a, b, c)} \right\rfloor
+$$
+
+As you can see, we need to add all cases with an odd number of elements and subtract all cases with an even number of elements.
+
+Since $n \leq 15$, we can use binary enumeration to enumerate all subsets and calculate the number of numbers that satisfy the condition, denoted as $cnt$. If $cnt \geq k$, then we need to find the smallest $x$ such that `check(x)` is true.
+
+At the start of the binary search, we define the left boundary $l=1$ and the right boundary $r={10}^{11}$. Then we continuously substitute the middle value $mid$ into the `check` function. If `check(mid)` is true, then we update the right boundary $r$ to $mid$, otherwise we update the left boundary $l$ to $mid+1$. Finally, we return $l$.
+
+The time complexity is $O(n \times 2^n \times \log (k \times M))$, where $n$ is the length of the array $coins$, and $M$ is the maximum value in the array.
 
 <!-- tabs:start -->
 
 ```python
+class Solution:
+    def findKthSmallest(self, coins: List[int], k: int) -> int:
+        def check(mx: int) -> bool:
+            cnt = 0
+            for i in range(1, 1 << len(coins)):
+                v = 1
+                for j, x in enumerate(coins):
+                    if i >> j & 1:
+                        v = lcm(v, x)
+                        if v > mx:
+                            break
+                m = i.bit_count()
+                if m & 1:
+                    cnt += mx // v
+                else:
+                    cnt -= mx // v
+            return cnt >= k
 
+        return bisect_left(range(10**11), True, key=check)
 ```
 
 ```java
+class Solution {
+    private int[] coins;
+    private int k;
 
+    public long findKthSmallest(int[] coins, int k) {
+        this.coins = coins;
+        this.k = k;
+        long l = 1, r = (long) 1e11;
+        while (l < r) {
+            long mid = (l + r) >> 1;
+            if (check(mid)) {
+                r = mid;
+            } else {
+                l = mid + 1;
+            }
+        }
+        return l;
+    }
+
+    private boolean check(long mx) {
+        long cnt = 0;
+        int n = coins.length;
+        for (int i = 1; i < 1 << n; ++i) {
+            long v = 1;
+            for (int j = 0; j < n; ++j) {
+                if ((i >> j & 1) == 1) {
+                    v = lcm(v, coins[j]);
+                    if (v > mx) {
+                        break;
+                    }
+                }
+            }
+            int m = Integer.bitCount(i);
+            if (m % 2 == 1) {
+                cnt += mx / v;
+            } else {
+                cnt -= mx / v;
+            }
+        }
+        return cnt >= k;
+    }
+
+    private long lcm(long a, long b) {
+        return a * b / gcd(a, b);
+    }
+
+    private long gcd(long a, long b) {
+        return b == 0 ? a : gcd(b, a % b);
+    }
+}
 ```
 
 ```cpp
+class Solution {
+public:
+    long long findKthSmallest(vector<int>& coins, int k) {
+        using ll = long long;
+        ll l = 1, r = 1e11;
+        int n = coins.size();
 
+        auto check = [&](ll mx) {
+            ll cnt = 0;
+            for (int i = 1; i < 1 << n; ++i) {
+                ll v = 1;
+                for (int j = 0; j < n; ++j) {
+                    if (i >> j & 1) {
+                        v = lcm(v, coins[j]);
+                        if (v > mx) {
+                            break;
+                        }
+                    }
+                }
+                int m = __builtin_popcount(i);
+                if (m & 1) {
+                    cnt += mx / v;
+                } else {
+                    cnt -= mx / v;
+                }
+            }
+            return cnt >= k;
+        };
+
+        while (l < r) {
+            ll mid = (l + r) >> 1;
+            if (check(mid)) {
+                r = mid;
+            } else {
+                l = mid + 1;
+            }
+        }
+        return l;
+    }
+};
 ```
 
 ```go
+func findKthSmallest(coins []int, k int) int64 {
+	var r int = 1e11
+	n := len(coins)
+	ans := sort.Search(r, func(mx int) bool {
+		cnt := 0
+		for i := 1; i < 1<<n; i++ {
+			v := 1
+			for j, x := range coins {
+				if i>>j&1 == 1 {
+					v = lcm(v, x)
+					if v > mx {
+						break
+					}
+				}
+			}
+			m := bits.OnesCount(uint(i))
+			if m%2 == 1 {
+				cnt += mx / v
+			} else {
+				cnt -= mx / v
+			}
+		}
+		return cnt >= k
+	})
+	return int64(ans)
+}
+
+func gcd(a, b int) int {
+	if b == 0 {
+		return a
+	}
+	return gcd(b, a%b)
+}
+
+func lcm(a, b int) int {
+	return a * b / gcd(a, b)
+}
+```
+
+```ts
+function findKthSmallest(coins: number[], k: number): number {
+    let [l, r] = [1n, BigInt(1e11)];
+    const n = coins.length;
+    const check = (mx: bigint): boolean => {
+        let cnt = 0n;
+        for (let i = 1; i < 1 << n; ++i) {
+            let v = 1n;
+            for (let j = 0; j < n; ++j) {
+                if ((i >> j) & 1) {
+                    v = lcm(v, BigInt(coins[j]));
+                    if (v > mx) {
+                        break;
+                    }
+                }
+            }
+            const m = bitCount(i);
+            if (m & 1) {
+                cnt += mx / v;
+            } else {
+                cnt -= mx / v;
+            }
+        }
+        return cnt >= BigInt(k);
+    };
+    while (l < r) {
+        const mid = (l + r) >> 1n;
+        if (check(mid)) {
+            r = mid;
+        } else {
+            l = mid + 1n;
+        }
+    }
+    return Number(l);
+}
+
+function gcd(a: bigint, b: bigint): bigint {
+    return b === 0n ? a : gcd(b, a % b);
+}
+
+function lcm(a: bigint, b: bigint): bigint {
+    return (a * b) / gcd(a, b);
+}
 
+function bitCount(i: number): number {
+    i = i - ((i >>> 1) & 0x55555555);
+    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
+    i = (i + (i >>> 4)) & 0x0f0f0f0f;
+    i = i + (i >>> 8);
+    i = i + (i >>> 16);
+    return i & 0x3f;
+}
 ```
 
 <!-- tabs:end -->
diff --git a/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/Solution.cpp b/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/Solution.cpp
new file mode 100644
index 0000000000000..7da81864c3250
--- /dev/null
+++ b/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/Solution.cpp	
@@ -0,0 +1,40 @@
+class Solution {
+public:
+    long long findKthSmallest(vector<int>& coins, int k) {
+        using ll = long long;
+        ll l = 1, r = 1e11;
+        int n = coins.size();
+
+        auto check = [&](ll mx) {
+            ll cnt = 0;
+            for (int i = 1; i < 1 << n; ++i) {
+                ll v = 1;
+                for (int j = 0; j < n; ++j) {
+                    if (i >> j & 1) {
+                        v = lcm(v, coins[j]);
+                        if (v > mx) {
+                            break;
+                        }
+                    }
+                }
+                int m = __builtin_popcount(i);
+                if (m & 1) {
+                    cnt += mx / v;
+                } else {
+                    cnt -= mx / v;
+                }
+            }
+            return cnt >= k;
+        };
+
+        while (l < r) {
+            ll mid = (l + r) >> 1;
+            if (check(mid)) {
+                r = mid;
+            } else {
+                l = mid + 1;
+            }
+        }
+        return l;
+    }
+};
\ No newline at end of file
diff --git a/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/Solution.go b/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/Solution.go
new file mode 100644
index 0000000000000..9d69dcd06c7fb
--- /dev/null
+++ b/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/Solution.go	
@@ -0,0 +1,37 @@
+func findKthSmallest(coins []int, k int) int64 {
+	var r int = 1e11
+	n := len(coins)
+	ans := sort.Search(r, func(mx int) bool {
+		cnt := 0
+		for i := 1; i < 1<<n; i++ {
+			v := 1
+			for j, x := range coins {
+				if i>>j&1 == 1 {
+					v = lcm(v, x)
+					if v > mx {
+						break
+					}
+				}
+			}
+			m := bits.OnesCount(uint(i))
+			if m%2 == 1 {
+				cnt += mx / v
+			} else {
+				cnt -= mx / v
+			}
+		}
+		return cnt >= k
+	})
+	return int64(ans)
+}
+
+func gcd(a, b int) int {
+	if b == 0 {
+		return a
+	}
+	return gcd(b, a%b)
+}
+
+func lcm(a, b int) int {
+	return a * b / gcd(a, b)
+}
\ No newline at end of file
diff --git a/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/Solution.java b/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/Solution.java
new file mode 100644
index 0000000000000..6f6bdbbc26c4a
--- /dev/null
+++ b/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/Solution.java	
@@ -0,0 +1,50 @@
+class Solution {
+    private int[] coins;
+    private int k;
+
+    public long findKthSmallest(int[] coins, int k) {
+        this.coins = coins;
+        this.k = k;
+        long l = 1, r = (long) 1e11;
+        while (l < r) {
+            long mid = (l + r) >> 1;
+            if (check(mid)) {
+                r = mid;
+            } else {
+                l = mid + 1;
+            }
+        }
+        return l;
+    }
+
+    private boolean check(long mx) {
+        long cnt = 0;
+        int n = coins.length;
+        for (int i = 1; i < 1 << n; ++i) {
+            long v = 1;
+            for (int j = 0; j < n; ++j) {
+                if ((i >> j & 1) == 1) {
+                    v = lcm(v, coins[j]);
+                    if (v > mx) {
+                        break;
+                    }
+                }
+            }
+            int m = Integer.bitCount(i);
+            if (m % 2 == 1) {
+                cnt += mx / v;
+            } else {
+                cnt -= mx / v;
+            }
+        }
+        return cnt >= k;
+    }
+
+    private long lcm(long a, long b) {
+        return a * b / gcd(a, b);
+    }
+
+    private long gcd(long a, long b) {
+        return b == 0 ? a : gcd(b, a % b);
+    }
+}
\ No newline at end of file
diff --git a/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/Solution.py b/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/Solution.py
new file mode 100644
index 0000000000000..d9edff9c1a53d
--- /dev/null
+++ b/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/Solution.py	
@@ -0,0 +1,19 @@
+class Solution:
+    def findKthSmallest(self, coins: List[int], k: int) -> int:
+        def check(mx: int) -> bool:
+            cnt = 0
+            for i in range(1, 1 << len(coins)):
+                v = 1
+                for j, x in enumerate(coins):
+                    if i >> j & 1:
+                        v = lcm(v, x)
+                        if v > mx:
+                            break
+                m = i.bit_count()
+                if m & 1:
+                    cnt += mx // v
+                else:
+                    cnt -= mx // v
+            return cnt >= k
+
+        return bisect_left(range(10**11), True, key=check)
diff --git a/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/Solution.ts b/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/Solution.ts
new file mode 100644
index 0000000000000..a6a78572c9fad
--- /dev/null
+++ b/solution/3100-3199/3116.Kth Smallest Amount With Single Denomination Combination/Solution.ts	
@@ -0,0 +1,51 @@
+function findKthSmallest(coins: number[], k: number): number {
+    let [l, r] = [1n, BigInt(1e11)];
+    const n = coins.length;
+    const check = (mx: bigint): boolean => {
+        let cnt = 0n;
+        for (let i = 1; i < 1 << n; ++i) {
+            let v = 1n;
+            for (let j = 0; j < n; ++j) {
+                if ((i >> j) & 1) {
+                    v = lcm(v, BigInt(coins[j]));
+                    if (v > mx) {
+                        break;
+                    }
+                }
+            }
+            const m = bitCount(i);
+            if (m & 1) {
+                cnt += mx / v;
+            } else {
+                cnt -= mx / v;
+            }
+        }
+        return cnt >= BigInt(k);
+    };
+    while (l < r) {
+        const mid = (l + r) >> 1n;
+        if (check(mid)) {
+            r = mid;
+        } else {
+            l = mid + 1n;
+        }
+    }
+    return Number(l);
+}
+
+function gcd(a: bigint, b: bigint): bigint {
+    return b === 0n ? a : gcd(b, a % b);
+}
+
+function lcm(a: bigint, b: bigint): bigint {
+    return (a * b) / gcd(a, b);
+}
+
+function bitCount(i: number): number {
+    i = i - ((i >>> 1) & 0x55555555);
+    i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
+    i = (i + (i >>> 4)) & 0x0f0f0f0f;
+    i = i + (i >>> 8);
+    i = i + (i >>> 16);
+    return i & 0x3f;
+}