AtCoder ABC132

文章讨论了解决Atcoder编程问题中的分层图最短路径问题,涉及DFS算法、分块处理数字、组合数学计算以及动态规划方法,利用模运算优化解题过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

陷入了“会做,但不完全会做”的状况
C
水题,排序找中间数两边的差值
D
组合数学
求把n个相同的球分到m个相同的盒子,1每个盒子至少一个球2每个盒子球不限的组合数
空挡插隔板法,高中数学

# -*- coding: utf-8 -*-
# @time     : 2023/6/2 13:30
# @author   : yhdu@tongwoo.cn
# @desc     :
# @file     : atcoder.py
# @software : PyCharm
import bisect
import copy
import sys
from sortedcontainers import SortedList
from collections import defaultdict, Counter, deque
from functools import lru_cache, cmp_to_key
import heapq
import math
sys.setrecursionlimit(100010)

mod = 10 ** 9 + 7


def pw(a, x):
    if x == 0:
        return 1
    temp = pw(a, x >> 1)
    if x & 1:
        return temp * temp * a % mod
    else:
        return temp * temp % mod


def inv(x):
    return pw(x, mod - 2)


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())
    R, B = n - k, k

    def cmb(x, y):
        if x < y:
            return 0
        return fac[x] * inv(fac[y]) * inv(fac[x - y]) % mod

    fac = [1] * 5005
    for i in range(2, 5005):
        fac[i] = fac[i - 1] * i % mod

    for i in range(1, B + 1):
        ans_r = cmb(R + 1, i)
        ans = cmb(B - 1, i - 1) * ans_r % mod
        print(ans)


if __name__ == "__main__":
    main()

E
一开始用dfs去求(3步能访问到的点对),明显TLE
分层图求最短路
原图分为3层,每个点拆成V0,V1,V2V_0,V_1,V_2V0,V1,V2
假如(u,v)(u,v)(u,v)间有一条有向边
把边拆成(u0,v1),(u1,v2),(u2,v3)(u_0,v_1),(u_1,v_2),(u_2,v_3)(u0,v1),(u1,v2),(u2,v3)
走三的倍数步能回到0层,这样只要能走到T0T_0T0点就有解

# -*- coding: utf-8 -*-
# @time     : 2023/6/2 13:30
# @author   : yhdu@tongwoo.cn
# @desc     :
# @file     : atcoder.py
# @software : PyCharm
import bisect
import copy
import sys
from sortedcontainers import SortedList
from collections import defaultdict, Counter, deque
from functools import lru_cache, cmp_to_key
import heapq
import math
sys.setrecursionlimit(100010)


def main():
    items = sys.version.split()
    if items[0] == '3.10.6':
        fp = open("in.txt")
    else:
        fp = sys.stdin
    n, m = map(int, fp.readline().split())
    g = [[] for _ in range(n * 3)]
    for i in range(m):
        u, v = map(int, fp.readline().split())
        u, v = u - 1, v - 1
        u0, u1, u2 = u, u + n, u + 2 * n
        v0, v1, v2 = v, v + n, v + 2 * n
        g[u0].append(v1)
        g[u1].append(v2)
        g[u2].append(v0)
    S, T = map(int, fp.readline().split())
    S, T = S - 1, T - 1

    vis = [-1] * (3 * n)
    qu = deque()
    qu.append(S)
    vis[S] = 0
    while qu:
        cur = qu.popleft()
        if cur == T:
            break
        for v in g[cur]:
            if vis[v] == -1:
                vis[v] = vis[cur] + 1
                qu.append(v)
    if vis[T] == -1:
        print(-1)
    else:
        print(vis[T] // 3)


if __name__ == "__main__":
    main()

F
分块
重要的是想清楚每一块代表的数字

# -*- coding: utf-8 -*-
# @time     : 2023/6/2 13:30
# @author   : yhdu@tongwoo.cn
# @desc     :
# @file     : atcoder.py
# @software : PyCharm
import bisect
import copy
import sys
from sortedcontainers import SortedList
from collections import defaultdict, Counter, deque
from functools import lru_cache, cmp_to_key
import heapq
import math
sys.setrecursionlimit(100010)


def main():
    items = sys.version.split()
    if items[0] == '3.10.6':
        fp = open("in.txt")
    else:
        fp = sys.stdin
    mod = 10 ** 9 + 7
    N, K = map(int, fp.readline().split())
    i = 1
    g = []
    """
    记录[l..r]的区间,每个区间中n//x都相同
    如10分为[1,1],[2,2],[3,3],[4,5],[6,10]
    记录区间中元素的数量g为[1,1],[2,1],[3,1],[5,2],[10,5] 第一个元素用不到,即为[1,1,1,2,5]
    dp时按照这些分块来推算
    f[2][4]即为当前长度为2,可以选择[4,5]时的从[1,1]...到[4,5]的总和
    f[i][j]可以通过选当前分块 f[i-1][l]+不选当前分块 f[i][j-1]计算而得
    观察可以发现l=m+1-j
    例如当前分块是[4,5],那么上一次能选到的是[1,1],[2,2] 即为f[i][4] = f[i][3] + f[i-1][2]
    """
    while i <= N:
        j = N // (N // i)       # i: left, r: right
        g.append(j - i + 1)
        i = j + 1
    m = len(g)
    g = [0] + g
    f = [[1] * (m + 1) for _ in range(K + 1)]
    for i in range(1, K + 1):
        f[i][0] = 0
        for j in range(1, m + 1):
            l = m + 1 - j
            f[i][j] = (f[i][j - 1] + g[j] * f[i - 1][l]) % mod
    print(f[K][m])


if __name__ == "__main__":
    main()

关于 AtCoder Beginner Contest 387 的信息如下: ### 关于 AtCoder Beginner Contest 387 AtCoder Beginner Contest (ABC) 是一项面向编程爱好者的定期在线竞赛活动。对于 ABC387,该赛事通常会在周末举行,并持续大约100分钟,在此期间参赛者需解决一系列算法挑战问题。 #### 比赛详情 - **举办平台**: AtCoder Online Judge System[^2] - **比赛时间长度**: 大约为1小时40分钟 - **难度级别**: 初学者友好型,适合那些刚开始接触竞争性程序设计的人群参与 - **题目数量**: 一般情况下会提供四到六道不同难度级别的题目供选手解答 #### 题目概览 虽然具体细节可能因官方发布而有所变化,但可以预期的是,这些题目将会覆盖基础的数据结构、字符串处理以及简单图论等方面的知识点。每一道题目的描述都会清晰给出输入输出格式说明及样例测试数据以便理解需求并验证解决方案的有效性。 为了获取最准确的比赛时间和确切的题目列表,请访问 [AtCoder 官方网站](https://atcoder.jp/) 并查看最新的公告板或直接导航至对应编号的具体页面来获得更新的信息。 ```python import requests from bs4 import BeautifulSoup def get_contest_info(contest_id): url = f"https://atcoder.jp/contests/{contest_id}" response = requests.get(url) if response.status_code == 200: soup = BeautifulSoup(response.text, 'html.parser') title_element = soup.find('title') problem_list_elements = soup.select('.panel.panel-default a[href^="/contests/{}/tasks"]'.format(contest_id)) contest_title = title_element.string.strip() if title_element else "Contest Title Not Found" problems = [element['href'].split('/')[-1] for element in problem_list_elements] return { "name": contest_title, "problems": problems } else: raise Exception(f"Failed to fetch data from {url}") abc_387_details = get_contest_info("abc387") print(abc_387_details) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值