AtCoder ABC146

C题
可以证明 A × N + B × d ( N ) A×N+B×d(N) A×N+B×d(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(100050)


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())
    s = fp.readline().strip()
    pre = {}
    qu = deque()
    qu.append((0, 0))
    for i in range(1, n + 1):
        while len(qu) > 0 and qu[0][1] < i - m:
            qu.popleft()
        if s[i] == '0':
            if len(qu) > 0:
                v = qu[0][0] + 1
                while len(qu) > 0:
                    if v < qu[-1][0]:
                        qu.pop()
                    else:
                        break
                pre[i] = qu[0][1]
                qu.append((v, i))
    ans = -1
    for item in qu:
        v, pos = item
        if pos == n:
            ans = v
    if ans == -1:
        print(-1)
        return
    cur = n
    a = []
    while cur != 0:
        a.append(cur - pre[cur])
        cur = pre[cur]
    a = a[::-1]
    print(*a)


if __name__ == "__main__":
    main()


D题
BFS不好写,还是要用DFS
题目比较简单,点出度最大的度数就是颜色的种类,从该点开始搜索

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


def main():
    items = sys.version.split()
    if items[0] == '3.10.6':
        fp = open("in.txt")
    else:
        fp = sys.stdin

    es = []
    n = int(fp.readline())
    g = [[] for _ in range(n)]
    m = {}
    for i in range(1, n):
        u, v = map(int, fp.readline().split())
        u, v = u - 1, v - 1
        if u > v:
            u, v = v, u
        es.append((u, v))
        g[u].append(v)
        g[v].append(u)

    root = -1
    mx = 0
    for u in range(n):
        if len(g[u]) > mx:
            mx, root = len(g[u]), u

    def dfs(node, fa, ec):
        idx = 0
        for chd in g[node]:
            if fa == chd:
                continue
            if idx == ec:
                idx += 1
            a, b = node, chd
            if a > b:
                a, b = b, a
            m[(a, b)] = idx
            dfs(chd, node, idx)
            idx += 1

    dfs(root, -1, -1)
    print(mx)
    for edge in es:
        u, v = edge
        print(m[(u, v)] + 1)


if __name__ == "__main__":
    main()

E题
本题需要列出公式
S ( r ) − S ( l − 1 ) ≡ r − ( l − 1 ) S(r)-S(l-1) \equiv r-(l-1) S(r)S(l1)r(l1)
变形为
S ( r ) − r ≡ S ( l − 1 ) − ( l − 1 ) S(r)-r \equiv S(l-1)-(l-1) S(r)rS(l1)(l1)
那么设 F ( i ) = S ( i ) − i F(i)=S(i)-i F(i)=S(i)i
然后遍历哈希就好。注意遍历到当前时有长度限制。

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


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())
    a = list(map(int, fp.readline().split()))
    s = [0] * (n + 1)

    for i in range(n):
        s[i + 1] = (s[i] + a[i]) % k
    for i in range(n + 1):
        s[i] = (s[i] - i) % k

    ct = Counter(s[:k])
    ans = 0
    for _, v in ct.items():
        ans += v * (v - 1) // 2

    for i in range(k, n + 1):
        ct[s[i - k]] -= 1
        v = s[i]
        ans += ct[v]
        ct[s[i]] += 1

    print(ans)


if __name__ == "__main__":
    main()

F题
经典模型。动态求前m个数的 min ⁡ \min min
比较暴力的方法是维护一个堆,但是不知道为什么一直RE,卡在第3个handmake点上。
于是改成了单调队列的方法。
维护一个单调递增的队列,队列头是 min ⁡ \min min,在队列后面插入,如果当前的数据比队列后面的数据要小,那么那些排在前面的就没有必要维护了(因为前面的肯定比当前数据先出队列)

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


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())
    s = fp.readline().strip()
    pre = {}
    qu = deque()
    qu.append((0, 0))
    for i in range(1, n + 1):
        while len(qu) > 0 and qu[0][1] < i - m:
            qu.popleft()
        if s[i] == '0':
            if len(qu) > 0:
                v = qu[0][0] + 1
                while len(qu) > 0:
                    if v < qu[-1][0]:
                        qu.pop()
                    else:
                        break
                pre[i] = qu[0][1]
                qu.append((v, i))
    ans = -1
    for item in qu:
        v, pos = item
        if pos == n:
            ans = v
    if ans == -1:
        print(-1)
        return
    cur = n
    a = []
    while cur != 0:
        a.append(cur - pre[cur])
        cur = pre[cur]
    a = a[::-1]
    print(*a)


if __name__ == "__main__":
    main()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值