C - Rally
从0到100模拟一遍位置最小的点
最小值实际上可以计算导数,将复杂度降为
O
(
1
)
O(1)
O(1)
D - Bouquet
组合数
2
n
−
1
−
C
(
n
,
a
)
−
C
(
n
,
b
)
2^{n}-1-C(n,a)-C(n,b)
2n−1−C(n,a)−C(n,b)
由于a.b都不大,因此可以做。注意用递推计算逆元.
# -*- coding: utf-8 -*-
# @time : 2023/6/2 13:30
# @file : atcoder.py
# @software : PyCharm
import bisect
import copy
import sys
from itertools import permutations
from sortedcontainers import SortedList
from collections import defaultdict, Counter, deque
from functools import lru_cache, cmp_to_key
import heapq
import math
sys.setrecursionlimit(1000)
mod = 10 ** 9 + 7
def pw(a, x):
if x == 1:
return a
temp = pw(a, x >> 1)
if x & 1:
return temp * temp * a % mod
else:
return temp * temp % mod
def main():
items = sys.version.split()
if items[0] == '3.10.6':
fp = open("in.txt")
else:
fp = sys.stdin
n, a, b = map(int, fp.readline().split())
t0 = pw(2, n) - 1
m = max(a, b) + 1
fac = [1] * m
for i in range(1, m):
fac[i] = fac[i - 1] * i % mod
inv = [1] * m
inv[m - 1] = pw(fac[m - 1], mod - 2)
for i in range(m - 2, -1, -1):
inv[i] = inv[i + 1] * (i + 1) % mod
def cmb(x, y):
ret = inv[y]
for i in range(x, x - y, -1):
ret = ret * i % mod
return ret
ans = (t0 - cmb(n, a) - cmb(n, b)) % mod
print(ans)
if __name__ == "__main__":
main()
E - Roaming
组合题
由于原始数组中每个数都为1,那么操作等价于将1变为0,然后看剩下的一些位置中如何放球。
枚举0的个数,设有i个位置为0,那么剩下的n-i位置中要安放n个球,且每个位置至少放1个球,
a个球放在b位置中每个位置至少一个球的方案数等价于在a个球的空隙中插b-1个隔板,因此为
C
(
a
−
1
,
b
−
1
)
C(a-1,b-1)
C(a−1,b−1)
# -*- coding: utf-8 -*-
# @time : 2023/6/2 13:30
# @file : atcoder.py
# @software : PyCharm
import bisect
import copy
import sys
from itertools import permutations
from sortedcontainers import SortedList
from collections import defaultdict, Counter, deque
from functools import lru_cache, cmp_to_key
import heapq
import math
sys.setrecursionlimit(1000)
def main():
items = sys.version.split()
if items[0] == '3.10.6':
fp = open("in.txt")
else:
fp = sys.stdin
n, k = map(int, fp.readline().split())
mod = 10 ** 9 + 7
ans = 0
fac = [1] * (n + 1)
for i in range(1, n + 1):
fac[i] = fac[i - 1] * i % mod
def pw(a, x):
if x == 1:
return a
t = pw(a, x >> 1)
if x & 1:
return t * t * a % mod
else:
return t * t % mod
inv = [1] * (n + 1)
inv[n] = pw(fac[n], mod - 2)
for i in range(n - 1, -1, -1):
inv[i] = inv[i + 1] * (i + 1) % mod
def c(x, y):
return fac[x] * inv[y] * inv[x - y] % mod
ans = 0
for i in range(k + 1):
if n - i - 1 >= 0:
ans += c(n - 1, n - i - 1) * c(n, i) % mod
ans %= mod
else:
break
print(ans)
if __name__ == "__main__":
main()