zoukankan      html  css  js  c++  java
  • 杜教筛

    其实不是什么特别毒瘤的东西

    用于求F = ∑ni = 1  f(i)

    然鹅F如果难算的话

    就找到好计算的 G,H

    使得f * g = h

    那么

    ni = 1  (f * g)(i) = ∑nj = 1 g(j) * ∑n / ik = 1  f(k) 

    ni = 1   (f * g) (i) = ∑ni = 1 h(i) 

    则可合并移项得出F的表示

    比较常见的是 mu 和 phi

    mu : F(n) = 1 - ∑ni = 2 F(n / i); 

    phi : F(n) = n * (n + 1) / 2 - ∑ni = 2 F(n / i);

    模板题

    这道题用到了一个很妙的结论

    n以内两两互质的数对个数

    S(n) = ∑ni = 1 nj = 1 [gcd(i, j) == 1]

            = ∑nd = 1 μ(d)  * (n / d); 下取整

    所以n以内欧拉函数和就是 ((S(n) - 1) / 2) + 1;

    链接 : 【模板】杜教筛(Sum)

    附上代码:

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <map>
     4 using namespace std;
     5 const int N = 2e6;
     6 bool ism[N];
     7 int prm[N], ps;
     8 int mu[N];
     9 map<int, long long> sm;
    10 
    11 void sieve(){
    12     mu[1] = ism[1] = 1;
    13     for(int i = 2; i < N; i++){
    14         if(!ism[i]) mu[i] = -1, prm[++ps] = i;
    15         for(int j = 1; j <= ps && prm[j] * i < N; j++){
    16             ism[prm[j] * i] = 1;
    17             if(!(i % prm[j])) break;
    18             mu[i * prm[j]] = -mu[i];
    19         }
    20     } 
    21     for(int i = 2; i < N; i++)
    22         mu[i] += mu[i - 1];
    23 }
    24 
    25 long long sum_mu(int x){
    26     if(x < N) return mu[x];
    27     if(sm.count(x)) return sm[x];
    28     int i = 2, j; 
    29     long long ret = 1;
    30     while(i <= x){
    31         j = x / (x / i);
    32         ret -= (long long)(j - i + 1) * sum_mu(x / i);
    33         i = j + 1;
    34     }
    35     return sm[x] = ret;
    36 }
    37 
    38 long long sum_phi(int x){
    39     long long ret = 0;
    40     long long i = 1, j;
    41     while(i <= x){
    42         j = x / (x / i);
    43         ret += (x / i) * (x / i) * (sum_mu(j) - sum_mu(i - 1));
    44         i = j + 1;
    45     }
    46     return ((ret - 1) >> 1) + 1;
    47 }
    48 
    49 int main(){
    50     sieve();
    51     int T; scanf("%d", &T);
    52     int x;
    53     long long a1, a2;
    54     while(T--){
    55         scanf("%d", &x);
    56         a1 = sum_mu(x); a2 = sum_phi(x);
    57         printf("%lld %lld
    ", a2, a1);
    58     }
    59     return 0;    
    60 }
    杜教筛
  • 相关阅读:
    chapter02“良/恶性乳腺癌肿瘤预测”的问题
    ASCII编码和Unicode编码的区别
    Spring AOP概述
    Spring 基于注解的配置
    Spring Bean作用域&FactoryBean
    Spring <bean> 之间的关系&整合多个配置文件
    Spring 方法注入
    Spring 简化装配Bean的配置方式
    Spring 注入参数详解
    vue-router 导航守卫
  • 原文地址:https://www.cnblogs.com/hjmmm/p/9416452.html
Copyright © 2011-2022 走看看