• 51nod1244 莫比乌斯函数之和 杜教筛


    虽然都写了,过也过了,还是觉得杜教筛的复杂度好玄学

    设f*g=h,∑f=S,

    则∑h=∑f(i)S(n/i下取整)

    把i=1时单独拿出来,得到

    S(n)=(∑h-∑2->n f(i)S(n/i下取整)

    右边的部分可以分块解决

    递归一下,≤一个阈值的暴力表出来

    注意阈值以上的也要记忆化

    复杂度不会算,但从本题来看过1e10没问题

     1 #include <bits/stdc++.h>
     2 #define MAX 5000000
     3 using namespace std;
     4 long long a,b,N;
     5 long long miu[MAX+1],p[MAX],ans[MAX];
     6 bool bo[MAX+1];
     7 long long work(long long n)
     8 {
     9     if(n<=MAX) return miu[n];
    10     if(ans[N/n]) return ans[N/n];
    11     long long ret=1;
    12     for(long long j=2;j<=n;)
    13     {
    14         long long nex=n/(n/j);
    15         ret-=(nex-j+1)*work(n/j);
    16         j=nex+1;
    17     }
    18     ans[N/n]=ret;
    19     return ret;
    20 }
    21 int main()
    22 {
    23     int sum=0;miu[1]=1;
    24     for(int i=2;i<=MAX;i++)
    25     {
    26         if(!bo[i])
    27             p[++sum]=i,miu[i]=-1;
    28         for(int j=1;j<=sum;j++)
    29         {
    30             if((long long)p[j]*i<=MAX)
    31             {
    32                 bo[p[j]*i]=1;
    33                 miu[i*p[j]]=-miu[i]*(bool)(i%p[j]);
    34             }
    35             else break;
    36             if(i%p[j]==0) break;
    37         }
    38     }
    39     for(int i=2;i<=MAX;i++)
    40         miu[i]+=miu[i-1];
    41     scanf("%lld%lld",&a,&b);
    42     N=b;
    43     long long ans1=work(b);
    44     for(int i=1;i<=MAX;i++)
    45         ans[i]=0;
    46     N=a-1;
    47     long long ans2=work(a-1);
    48     printf("%lld
    ",ans1-ans2);
    49     return 0;
    50 }
  • 相关阅读:
    java堆
    本地方法栈
    java虚拟机栈
    Java 程序计数器
    面向对象 基本概念 复习
    if __name__=='__main__'
    偏函数与模块
    可变参数与关键字参数(复习材料)
    匿名函数
    闭包
  • 原文地址:https://www.cnblogs.com/wanglichao/p/6836665.html
Copyright © 2020-2023  润新知