AtCoder ABC154

C - Distinct or Not
签到题,注意大小写和以前的不一样

D - Dice in Line
签到题2,用个窗口即可

E - Almost Everywhere Zero
数位DP(搜索)的例题
pos表示当前搜索到的位置(开始为0,结束为n)
num表示已经使用的非0数字个数
cap表示搜索是否被限制,当之前搜索的数字比s小时cap=0,否则cap=1,开始时cap=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

    s = fp.readline().strip()
    n = len(s)
    k = int(fp.readline())

    @lru_cache(None)
    def get(pos, cap, num):
        if num == k:
            return 1
        if pos == n:
            return 0
        ret = 0
        si = int(s[pos])
        if cap == 0:
            ret += get(pos + 1, cap, num)
            ret += get(pos + 1, cap, num + 1) * 9
        else:
            if si == 0:
                ret += get(pos + 1, cap, num)
            else:
                ret += get(pos + 1, cap, num + 1)
                ret += get(pos + 1, 0, num + 1) * (si - 1)
                ret += get(pos + 1, 0, num)
        return ret

    ans = get(0, 1, 0)
    print(ans)


if __name__ == "__main__":
    main()

F - Many Many Paths

组合数学
显见
1.每个(r,c)点上的数都是一个组合数 C ( r + c , c ) C(r+c,c) C(r+c,c)
2.可以用容斥原理将ans拆成 g ( r 2 , c 2 ) − g ( r 2 , c 1 − 1 ) − g ( r 1 − 1 , c 2 ) + g ( r 1 − 1 , c 1 − 1 ) g(r_2,c_2)-g(r_2,c_1-1)-g(r_1-1,c_2)+g(r_1-1,c_1-1) g(r2,c2)g(r2,c11)g(r11,c2)+g(r11,c11)
其中 g g g函数是从(0,0)到(r,c)点的所有组合数的和。
将g按列分解(行也一样)
得到 g = C ( 0 , 0 ) + C ( 1 , 0 ) + . . . + C ( r , 0 ) + C ( 1 , 1 ) + C ( 2 , 1 ) + . . . + C ( r + 1 , 1 ) + . . . . C ( 1 + c , c ) + C ( 2 + c , c ) + . . . + C ( r + c , c ) g=C(0,0)+C(1,0)+...+C(r,0)+\\ C(1,1)+C(2,1)+...+C(r+1,1) + \\ ....\\ C(1+c,c)+C(2+c,c)+...+C(r+c,c) g=C(0,0)+C(1,0)+...+C(r,0)+C(1,1)+C(2,1)+...+C(r+1,1)+....C(1+c,c)+C(2+c,c)+...+C(r+c,c)
每一行都可以规约为 C ( i + c + 1 , c ) C(i+c+1, c) C(i+c+1,c)
这样可以写出一个 O ( n ) O(n) O(n)算法

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

    r1, c1, r2, c2 = map(int, fp.readline().split())
    mod = 10 ** 9 + 7
    fac = [1] * 2000002
    iv = [1] * 2000002
    for i in range(1, 2000002):
        fac[i] = fac[i - 1] * i % mod

    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

    iv[1000001] = pw(fac[1000001], mod - 2)
    for i in range(1000000, -1, -1):
        iv[i] = (iv[i + 1] * (i + 1)) % mod

    def cmb(x, y):
        return fac[x] * iv[y] * iv[x - y] % mod

    def get(r, c):
        ret = 0
        for i in range(1, r + 2):
            ret = (ret + cmb(i + c, c)) % mod
        return ret

    a0, a1, a2, a3 = get(r2, c2), get(r1 - 1, c2), get(r2, c1 - 1), get(r1 - 1, c1 - 1)
    ans = (a0 - a1 - a2 + a3) % mod
    print(ans)


if __name__ == "__main__":
    main()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值