AtCoder ABC156

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) 2n1C(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(a1,b1)

# -*- 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()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值