@@ -100,32 +100,239 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3800-3899/3881.Di
100100
101101<!-- solution:start -->
102102
103- ### 方法一
103+ ### 方法一:组合数学 + 枚举
104+
105+ 位置 $\textit{pos}$ 左边有 $\textit{pos}$ 个人,右边有 $n - \textit{pos} - 1$ 个人。
106+
107+ 我们枚举左边可见的人数 $a$,则右边可见的人数为 $b = k - a$。如果 $a$ 和 $b$ 都合法,那么答案增加 $2 \cdot \binom{\textit{pos}}{a} \cdot \binom{n - \textit{pos} - 1}{b}$。其中 $2$ 是因为位于下标 $\textit{pos}$ 的人可以选择 'L' 或 'R'。
108+
109+ 对于组合数 $\binom{n}{k}$,我们可以预处理阶乘和逆元来快速计算。
110+
111+ 时间复杂度 $O(n)$,其中 $n$ 是输入的整数 $n$。空间复杂度 $O(n)$ 用于存储阶乘和逆元。
104112
105113<!-- tabs:start -->
106114
107115#### Python3
108116
109117``` python
110-
118+ N = 100001
119+ MOD = 10 ** 9 + 7
120+ f = [1 ] * N
121+ g = [1 ] * N
122+ for i in range (1 , N):
123+ f[i] = f[i - 1 ] * i % MOD
124+ g[i] = pow (f[i], MOD - 2 , MOD )
125+
126+
127+ def comb (n , k ):
128+ return f[n] * g[k] * g[n - k] % MOD
129+
130+
131+ class Solution :
132+ def countVisiblePeople (self , n : int , pos : int , k : int ) -> int :
133+ l, r = pos, n - pos - 1
134+ ans = 0
135+ for a in range (min (k, l) + 1 ):
136+ b = k - a
137+ if b <= r:
138+ ans += 2 * comb(l, a) * comb(r, b)
139+ ans %= MOD
140+ return ans
111141```
112142
113143#### Java
114144
115145``` java
116-
146+ class Solution {
147+ private static final int N = 100001 ;
148+ private static final int MOD = (int ) 1e9 + 7 ;
149+ private static final long [] F = new long [N ];
150+ private static final long [] G = new long [N ];
151+
152+ static {
153+ F [0 ] = 1 ;
154+ G [0 ] = 1 ;
155+ for (int i = 1 ; i < N ; ++ i) {
156+ F [i] = F [i - 1 ] * i % MOD ;
157+ G [i] = qmi(F [i], MOD - 2 , MOD );
158+ }
159+ }
160+
161+ public static long qmi (long a , long k , long p ) {
162+ long res = 1 ;
163+ while (k != 0 ) {
164+ if ((k & 1 ) == 1 ) {
165+ res = res * a % p;
166+ }
167+ k >> = 1 ;
168+ a = a * a % p;
169+ }
170+ return res;
171+ }
172+
173+ public static long comb (int n , int k ) {
174+ return (F [n] * G [k] % MOD ) * G [n - k] % MOD ;
175+ }
176+
177+ public int countVisiblePeople (int n , int pos , int k ) {
178+ int l = pos, r = n - pos - 1 ;
179+ long ans = 0 ;
180+
181+ for (int a = 0 ; a <= Math . min(k, l); ++ a) {
182+ int b = k - a;
183+ if (b <= r) {
184+ ans = (ans + 2 * comb(l, a) % MOD * comb(r, b) % MOD ) % MOD ;
185+ }
186+ }
187+ return (int ) ans;
188+ }
189+ }
117190```
118191
119192#### C++
120193
121194``` cpp
122-
195+ int N = 100001 ;
196+ int MOD = 1e9 + 7 ;
197+ long long f[100001 ];
198+ long long g[100001 ];
199+
200+ long long qmi (long long a, long long k, long long p) {
201+ long long res = 1;
202+ while (k != 0) {
203+ if ((k & 1) == 1) {
204+ res = res * a % p;
205+ }
206+ k >>= 1;
207+ a = a * a % p;
208+ }
209+ return res;
210+ }
211+
212+ int init = [ ] ( ) {
213+ f[ 0] = 1;
214+ g[ 0] = 1;
215+ for (int i = 1; i < N; ++i) {
216+ f[ i] = f[ i - 1] * i % MOD;
217+ g[ i] = qmi(f[ i] , MOD - 2, MOD);
218+ }
219+ return 0;
220+ }();
221+
222+ long long comb(int n, int k) {
223+ return f[ n] * g[ k] % MOD * g[ n - k] % MOD;
224+ }
225+
226+ class Solution {
227+ public:
228+ int countVisiblePeople(int n, int pos, int k) {
229+ int l = pos, r = n - pos - 1;
230+ long long ans = 0;
231+
232+ for (int a = 0; a <= min(k, l); ++a) {
233+ int b = k - a;
234+ if (b <= r) {
235+ ans = (ans + 2 * comb(l, a) % MOD * comb(r, b) % MOD) % MOD;
236+ }
237+ }
238+ return ans;
239+ }
240+ };
123241```
124242
125243#### Go
126244
127245```go
246+ package main
247+
248+ const N = 100001
249+ const MOD = 1e9 + 7
250+
251+ var f = make([]int, N)
252+ var g = make([]int, N)
253+
254+ func qmi(a, k, p int) int {
255+ res := 1
256+ for k != 0 {
257+ if k&1 == 1 {
258+ res = res * a % p
259+ }
260+ k >>= 1
261+ a = a * a % p
262+ }
263+ return res
264+ }
265+
266+ func init() {
267+ f[0], g[0] = 1, 1
268+ for i := 1; i < N; i++ {
269+ f[i] = f[i-1] * i % MOD
270+ g[i] = qmi(f[i], MOD-2, MOD)
271+ }
272+ }
273+
274+ func comb(n, k int) int {
275+ return f[n] * g[k] % MOD * g[n-k] % MOD
276+ }
277+
278+ func countVisiblePeople(n int, pos int, k int) int {
279+ l, r := pos, n-pos-1
280+ ans := 0
281+
282+ for a := 0; a <= min(k, l); a++ {
283+ b := k - a
284+ if b <= r {
285+ ans = (ans + 2*comb(l, a)%MOD*comb(r, b)%MOD) % MOD
286+ }
287+ }
288+ return ans
289+ }
290+ ```
128291
292+ #### TypeScript
293+
294+ ``` ts
295+ const N = 100001 ;
296+ const MOD = 1000000007n ;
297+
298+ const f: bigint [] = Array (N ).fill (0n );
299+ const g: bigint [] = Array (N ).fill (0n );
300+
301+ function qmi(a : bigint , k : bigint , p : bigint ): bigint {
302+ let res = 1n ;
303+ while (k > 0n ) {
304+ if (k & 1n ) res = (res * a ) % p ;
305+ k >>= 1n ;
306+ a = (a * a ) % p ;
307+ }
308+ return res ;
309+ }
310+
311+ f [0 ] = 1n ;
312+ g [0 ] = 1n ;
313+ for (let i = 1 ; i < N ; i ++ ) {
314+ f [i ] = (f [i - 1 ] * BigInt (i )) % MOD ;
315+ g [i ] = qmi (f [i ], MOD - 2n , MOD );
316+ }
317+
318+ function comb(n : number , k : number ): bigint {
319+ return (((f [n ] * g [k ]) % MOD ) * g [n - k ]) % MOD ;
320+ }
321+
322+ function countVisiblePeople(n : number , pos : number , k : number ): number {
323+ const l = pos ,
324+ r = n - pos - 1 ;
325+ let ans = 0n ;
326+
327+ for (let a = 0 ; a <= Math .min (k , l ); a ++ ) {
328+ const b = k - a ;
329+ if (b <= r ) {
330+ ans = (ans + ((((2n * comb (l , a )) % MOD ) * comb (r , b )) % MOD )) % MOD ;
331+ }
332+ }
333+
334+ return Number (ans );
335+ }
129336```
130337
131338<!-- tabs:end -->
0 commit comments