8048. 最大二进制奇数
class Solution:
def maximumOddBinaryNumber(self, s: str) -> str:
cnt = s.count('1')
n = len(s)
return '1'*(cnt-1)+'0'*(n-cnt)+'1'
100048. 美丽塔 II
100049. 美丽塔 I
t2可以平方,那么枚举每个位置作为最大值,前后扩展即可。重点说说T3的O(n)单调栈做法。
class Solution:
def maximumSumOfHeights(self, a):
n = len(a)
pre = [0] * (n)
suf = [0] * (n)
st = []
for i, v in enumerate(a):
while st and v < a[st[-1]]:
st.pop()
if st:
pre[i] = pre[st[-1]] + (i-st[-1])*v
else:
pre[i] = v*(i+1)
st.append(i)
st = []
for i in range(n-1,-1,-1):
v = a[i]
while st and v < a[st[-1]]:
st.pop()
if st:
suf[i] = suf[st[-1]] + (st[-1]-i)*v
else:
suf[i] = v*(n-i)
st.append(i)
ans = n
for x,y,z in zip(pre,suf,a):
ans = max(ans, x+y-z)
return ans
100047. 统计树中的合法路径数目
触达
的合数其实是相连的,而且数量汇聚到了父节点(第一次dfs),那么把子节点直接赋值成父节点即可。class PrimeTable:
def __init__(self, n: int) -> None:
self.n = n
self.primes = primes = [] # 所有n以内的质数
self.min_div = min_div = [0] * (n + 1) # md[i]代表i的最小(质)因子
min_div[1] = 1
# 欧拉筛O(n),顺便求出min_div
for i in range(2, n + 1):
if not min_div[i]:
primes.append(i)
min_div[i] = i
for p in primes:
if i * p > n: break
min_div[i * p] = p
if i % p == 0:
break
def is_prime(self, x: int):
"""检测是否是质数,最坏是O(sqrt(x)"""
if x < 3: return x == 2
if x <= self.n: return self.min_div[x] == x
for i in range(2, int(x ** 0.5) + 1):
if x % i == 0: return False
return True
def prime_factorization(self, x: int):
"""分解质因数,复杂度
1. 若x>n则需要从2模拟到sqrt(x),如果中间x降到n以下则走2;最坏情况,不含低于n的因数,则需要开方复杂度
2. 否则x质因数的个数,那么最多就是O(lgx)"""
n, min_div = self.n, self.min_div
for p in range(2, int(x ** 0.5) + 1):
if x <= n: break
if x % p == 0:
cnt = 0
while x % p == 0: cnt += 1; x //= p
yield p, cnt
while 1 < x <= n:
p, cnt = min_div[x], 0
while x % p == 0: cnt += 1; x //= p
yield p, cnt
if x >= n and x > 1:
yield x, 1
def get_factors(self, x: int):
"""求x的所有因数,包括1和x"""
factors = [1]
for p, b in self.prime_factorization(x):
n = len(factors)
for j in range(1, b + 1):
for d in factors[:n]:
factors.append(d * (p ** j))
return factors
def mr_is_prime(self, x):
"""
Miller-Rabin 检测. 检测x是否是质数,置信度: 1 - (1/4)^k. 复杂度k*log^3
但是longlong以内可以用k==3或7的代价,换取100%置信度
https://zhuanlan.zhihu.com/p/349360074
"""
if x < 3 or x % 2 == 0:
return x == 2
if x % 3 == 0:
return x == 3
u, t = x - 1, 0
while not u & 1:
u >>= 1
t += 1
ud = (2, 325, 9375, 28178, 450775, 9780504, 1795265022) # long long 返回用这个7个数检测100%正确
# ud = (2, 7, 61) # int 返回用这3个数检测100%正确
# for _ in range(k):
# a = random.randint(2, x - 2)
for a in ud:
v = pow(a, u, x)
if v == 1 or v == x - 1 or v == 0:
continue
for j in range(1, t + 1):
v = v * v % x
if v == x - 1 and j != t:
v = 1
break
if v == 1:
return False
if v != 1:
return False
return True
# pt = PrimeTable(1000)
#
# # 求质数
primes = set(PrimeTable(10 ** 5+10).primes)
class Solution:
def countPaths(self, n: int, edges: List[List[int]]) -> int:
g = [[] for _ in range(n)]
for u,v in edges:
g[u-1].append(v-1)
g[v-1].append(u-1)
f = [0] * n
def dfs(u,fa):
if (u+1) not in primes:
f[u] += 1
for v in g[u]:
if v != fa:
dfs(v, u)
if (u+1) not in primes:
# if u == 0:
# print(f)
f[u] += f[v]
def reroot(u,fa):
for v in g[u]:
if v != fa:
if (v+1) not in primes and (u+1) not in primes:
f[v] = f[u]
reroot(v, u)
dfs(0,-1)
reroot(0,-1)
ans = 0
for u in range(n):
if (u+1) in primes:
p = 0
for v in g[u]:
if (v+1) not in primes:
ans += (f[v]) * p + f[v]
p += f[v]
return ans