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(l−1)≡r−(l−1)
变形为
S ( r ) − r ≡ S ( l − 1 ) − ( l − 1 ) S(r)-r \equiv S(l-1)-(l-1) S(r)−r≡S(l−1)−(l−1)
那么设 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()