defprimes_with_sieve(N): is_prime = [1for i inrange(N+1)] is_prime[0]=is_prime[1]=0 for i inrange(2,N+1): if is_prime[i]: for j inrange(i*i,N+1,i): is_prime[j] = 0 return is_prime
defprimes_with_sieve(N): is_prime = [1for i inrange(N+1)] is_prime[0]=is_prime[1]=0 for i inrange(2,N+1): if is_prime[i]: for j inrange(i*i,N+1,i): is_prime[j] = 0 return is_prime
defprimes_from_prime_bool(arr): primes = [0] for i inrange(2,len(arr)): if arr[i]: primes.append(i) return primes
defLegendre_s_Formula(N): import math sqrt_N=math.isqrt(N) # sieve for sqrt_N pi = primes_with_sieve(sqrt_N) primes = primes_from_prime_bool(pi) for i inrange(2,sqrt_N+1): pi[i]+=pi[i-1] pi_sqrt_N=pi[sqrt_N] m_k = [1] for i inrange(1,len(primes)): m_k.append(m_k[-1]*primes[i]) if m_k[-1] > N: break
cnt = pi_sqrt_N-1# pi(N) = pi(sqrt(N))-1 +phi(n,pi(sqrt(n))) task = [(1,N,pi_sqrt_N)] # coef, x, a defeuler_phi(val,k): for i inrange(1,k+1): val*=primes[i]-1 val//=primes[i] return val
itr = 0 while itr < len(task): coef,x,a = task[itr] # task.pop(0) if a==1: cnt += coef*(x-x//2) elif x<=1: cnt += coef*x; elif a>=x: assert x<=sqrt_N cnt += coef*1 elif a < len(m_k) and x > m_k[a]: # phi(s m_k+t,k) = s phi(m_k,k) + phi(t,k) cnt += coef*(x//m_k[a])*euler_phi(m_k[a],a) task.append((coef ,x%m_k[a],a)) elif a < len(m_k) and x*2 > m_k[a] and x < m_k[a]: cnt += coef*euler_phi(m_k[a],a) task.append((coef*-1,m_k[a]-x-1,a)) else: task.append((coef*-1,x//primes[a],a-1)) task.append((coef ,x ,a-1)) itr+=1
defprimes_with_sieve(N): is_prime = [1for i inrange(N+1)] is_prime[0]=is_prime[1]=0 for i inrange(2,N+1): if is_prime[i]: for j inrange(i*i,N+1,i): is_prime[j] = 0 return is_prime
defprimes_from_prime_bool(arr): primes = [0] for i inrange(2,len(arr)): if arr[i]: primes.append(i) return primes
defmeissel(N): # $\pi(x) = \phi(x,a)-1+a -\sum_{i\ge a+1}^{b}\pi(\frac{x}{p_i})+\frac{1}{2}(a+b-1)(b-a)$, # 其中$a=\pi(x^{\frac{1}{3}}),b=\pi(x^{\frac{1}{2}})$ import math sqrt_N=math.isqrt(N) # sieve for sqrt_N pi = primes_with_sieve(sqrt_N) primes = primes_from_prime_bool(pi) # 1-index 即是个数也是下标 for i inrange(2,sqrt_N+1): pi[i]+=pi[i-1]
defmeissel_recursive(x): # a = pi(x^1/3) a = 1 for i inrange(1,len(primes)): if primes[i]**3 > x: assert i > 1 a = i-1 break # assert a == pi[math.floor(x**(1/3))] 浮点数问题
# b = pi(x^1/2) b = pi[math.isqrt(x)]
# (a,b] cnt = a-1+(a+b-1)*(b-a)//2 # -sum pi(x/p_i),i=a+1..b for p in primes[a+1:b+1]: if x//p < len(pi): cnt -= pi[x//p] else: cnt -= meissel_recursive(x//p)
# +phi(x,a) task = [(1,x,a)] # coef, x, a defeuler_phi(val,k): for i inrange(1,k+1): val*=primes[i]-1 val//=primes[i] return val
import time defprimes_with_sieve(N): is_prime = [1for i inrange(N+1)] is_prime[0]=is_prime[1]=0 for i inrange(2,N+1): if is_prime[i]: for j inrange(i*i,N+1,i): is_prime[j] = 0 return is_prime
defprimes_from_prime_bool(arr): primes = [0] for i inrange(2,len(arr)): if arr[i]: primes.append(i) return primes
defn_1_div_pwr(n,pwr): # python3 只有isqrt没有1/3? # return int(n**(1/pwr)): l = 0 r = n+1 while r-l>1: mid = (l+r)//2 if mid**pwr > n: r = mid else: l = mid return l
defmeissel_lehmer(N): # $\pi(x) = \phi(x,a)-1+a # - \sum_{i=[a+1,b]}(\pi(\frac{x}{p_i})-(i-1)) # - \sum_{i=[a+1,c]} \sum_{j=[i,\pi(\sqrt(x/p_i))(\pi(\frac{x}{p_ip_j})-(j-1)) # 其中 $a=\pi(x^{\frac{1}{4}}), # b=\pi(x^{\frac{1}{2}})$ # c=\pi(x^{\frac{1}{3}})$ import math sqrt_N=math.isqrt(N) pi = primes_with_sieve(sqrt_N) primes = primes_from_prime_bool(pi) # 1-index 即是个数也是下标 for i inrange(2,sqrt_N+1): pi[i]+=pi[i-1]
definner_recursive(x): if x < len(pi): return pi[x] a = max(pi[n_1_div_pwr(x,4)],1) c = max(pi[n_1_div_pwr(x,3)],a) b = max(pi[n_1_div_pwr(x,2)],c)
cnt = a-1 # -sum pi(x/p_i)-(i-1),i=a+1..b for i inrange(a+1,b+1): cnt -= inner_recursive(x//primes[i]) - (i-1)
# - \sum_{i=[a+1,c]} \sum_{j=[i,\pi(\sqrt(x/p_i))(\pi(\frac{x}{p_ip_j})-(j-1)) for i inrange(a+1,c+1): mxj = pi[math.isqrt(x//primes[i])] for j inrange(i,mxj+1): cnt -= inner_recursive(x//primes[i]//primes[j])-(j-1)
query(l,r,ql,qr,i,j): assert(l <= ql and qr <= r) if(l == ql and qr == r) return ask(i,j); m = (l+r)/2 if(ql < m) ret += query(l,m,ql,min(m,qr),i-1,j*2) if(qr > m) ret += query(m,r,max(m,ql),qr,i-1,j*2+1) return ret
ans = query(0,1 << n,l,r,n,0)
这个问题是 不能保证最小次数
例如 求a[0..14],那么 只需要 a[0..15] - a[15..15] 两次 而不是3次
这个从二进制上看单侧
14 = 1110, 也就是连续的最多需要两次可以计算出
所以想的是 l 的二进制 变为 r的二进制过程中, 只能 加 或 减 2的幂次,且幂次不能超过当前值的最高位的1