classSolution:defmaximumSumOfHeights(self, a):
n =len(a)
pre =[0]*(n)
suf =[0]*(n)
st =[]for i, v inenumerate(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 inrange(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 inzip(pre,suf,a):
ans =max(ans, x+y-z)return ans
classPrimeTable: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_divfor i inrange(2, n +1):ifnot 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:breakdefis_prime(self, x:int):"""检测是否是质数,最坏是O(sqrt(x)"""if x <3:return x ==2if x <= self.n:return self.min_div[x]== x
for i inrange(2,int(x **0.5)+1):if x % i ==0:returnFalsereturnTruedefprime_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 inrange(2,int(x **0.5)+1):if x <= n:breakif x % p ==0:
cnt =0while x % p ==0: cnt +=1; x //= p
yield p, cnt
while1< x <= n:
p, cnt = min_div[x],0while x % p ==0: cnt +=1; x //= p
yield p, cnt
if x >= n and x >1:yield x,1defget_factors(self, x:int):"""求x的所有因数,包括1和x"""
factors =[1]for p, b in self.prime_factorization(x):
n =len(factors)for j inrange(1, b +1):for d in factors[:n]:
factors.append(d *(p ** j))return factors
defmr_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 <3or x %2==0:return x ==2if x %3==0:return x ==3
u, t = x -1,0whilenot 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 ==1or v == x -1or v ==0:continuefor j inrange(1, t +1):
v = v * v % x
if v == x -1and j != t:
v =1breakif v ==1:returnFalseif v !=1:returnFalsereturnTrue# pt = PrimeTable(1000)## # 求质数
primes =set(PrimeTable(10**5+10).primes)classSolution:defcountPaths(self, n:int, edges: List[List[int]])->int:
g =[[]for _ inrange(n)]for u,v in edges:
g[u-1].append(v-1)
g[v-1].append(u-1)
f =[0]* n
defdfs(u,fa):if(u+1)notin primes:
f[u]+=1for v in g[u]:if v != fa:
dfs(v, u)if(u+1)notin primes:# if u == 0:# print(f)
f[u]+= f[v]defreroot(u,fa):for v in g[u]:if v != fa:if(v+1)notin primes and(u+1)notin primes:
f[v]= f[u]
reroot(v, u)
dfs(0,-1)
reroot(0,-1)
ans =0for u inrange(n):if(u+1)in primes:
p =0for v in g[u]:if(v+1)notin primes:
ans +=(f[v])* p + f[v]
p += f[v]return ans