zoukankan      html  css  js  c++  java
  • 杜教筛 && bzoj3944 Sum

    Description

    Input

    一共T+1行
    第1行为数据组数T(T<=10)
    第2~T+1行每行一个非负整数N,代表一组询问

    Output

    一共T行,每行两个用空格分隔的数ans1,ans2

    Sample Input

    6
    1
    2
    8
    13
    30
    2333

    Sample Output

    1 1
    2 0
    22 -2
    58 -3
    278 -3
    1655470 2

    正解:线性筛+杜教筛。

    杜教筛板子题。然而感觉自己还不是很理解的样子。。

    唐老师博客:http://blog.csdn.net/skywalkert/article/details/50500009

    xLightGod博客:http://blog.xlightgod.com/dirichlet%E5%8D%B7%E7%A7%AF%E4%B8%8E%E6%9D%9C%E6%95%99%E7%AD%9B/

    杜教筛可以在低于线性复杂度的时间内求出一些积性函数的前缀和。

    为了更快地求$F(i)=sum_{i=1}^{n}f(i)$,我们构造一个函数$g(n)$,求出$(f*g)(n)$的前缀和。

    $sum_{i=1}^{n}(f*g)(i)=sum_{i=1}^{n}sum_{d|i}f(d)g(frac{i}{d})=sum_{ij<=n}f(i)g(j)=sum_{i=1}^{n}g(i)F(left lfloor frac{n}{i} ight floor)$

    所以$g(1)F(n)=sum_{i=1}^{n}(f*g)(i)-sum_{i=2}^{n}g(i)F(left lfloor frac{n}{i} ight floor)$

    于是我们的目标就是快速求出$sum_{i=1}^{n}(f*g)(i)$和$g(i)$的前缀和。这样我们的复杂度就是$O(n^{frac{3}{4}})$,如果我们将$O(n^{frac{2}{3}})$以内的$F(i)$预处理,那么复杂度就可以降到$O(n^{frac{2}{3}})$(复杂度怎么证。。)

    $g$一般取恒等函数$I$。

    所以求$sum_{i=1}^{n}mu(i)$,那就是求$sum_{i=1}^{n}sum_{d|i}mu(d)-sum_{i=2}^{n}F(left lfloor frac{n}{i} ight floor)$

    则$Ans=1-sum_{i=2}^{n}F(left lfloor frac{n}{i} ight floor)$

    求$sum_{i=1}^{n}phi(i)$,那就是求$sum_{i=1}^{n}sum_{d|i}phi(d)-sum_{i=2}^{n}F(left lfloor frac{n}{i} ight floor)$

    则$Ans=frac{n(n+1)}{2}-sum_{i=2}^{n}F(left lfloor frac{n}{i} ight floor)$

    于是$Ans$的后面那一坨我们用记忆化搜索,空间开不了??我是用的map。开始先把2500000以内的答案线性筛预处理出来,然后搜索即可。(为什么是2500000,因为我发现这样快一些。。复杂度太玄学了。。)

     1 //It is made by wfj_2048~
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <complex>
     5 #include <cstring>
     6 #include <cstdlib>
     7 #include <cstdio>
     8 #include <vector>
     9 #include <cmath>
    10 #include <queue>
    11 #include <stack>
    12 #include <map>
    13 #include <set>
    14 #define inf (1<<30)
    15 #define N (2500010)
    16 #define il inline
    17 #define RG register
    18 #define ll long long
    19 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    20 
    21 using namespace std;
    22 
    23 struct node{ ll phi,mu; }ans;
    24 
    25 map <ll,ll> Phi,Mu;
    26 ll vis[N],phi[N],mu[N],prime[N],n,cnt;
    27 
    28 il ll gi(){
    29     RG ll x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    30     if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x;
    31 }
    32 
    33 il void sieve(){
    34     vis[1]=phi[1]=mu[1]=1;
    35     for (RG ll i=2;i<N;++i){
    36     if (!vis[i]) phi[i]=i-1,mu[i]=-1,prime[++cnt]=i;
    37     for (RG ll j=1,k=i*prime[j];j<=cnt && k<N;++j,k=i*prime[j]){
    38         vis[k]=1;
    39         if (i%prime[j]) phi[k]=phi[i]*phi[prime[j]],mu[k]=-mu[i];
    40         else{ phi[k]=phi[i]*prime[j]; break; }
    41     }
    42     }
    43     for (RG ll i=2;i<N;++i) phi[i]+=phi[i-1],mu[i]+=mu[i-1]; return;
    44 }
    45 
    46 il node du(RG ll n){
    47     if (n<N) return (node){phi[n],mu[n]};
    48     if (Phi[n]) return (node){Phi[n],Mu[n]};
    49     RG ll ans1=n*(n+1)>>1,ans2=1,pos=0; RG node res;
    50     for (RG ll i=2;i<=n;i=pos+1){
    51     pos=n/(n/i),res=du(n/i);
    52     ans1-=(pos-i+1)*res.phi;
    53     ans2-=(pos-i+1)*res.mu;
    54     }
    55     Phi[n]=ans1,Mu[n]=ans2;
    56     return (node){ans1,ans2};
    57 }
    58 
    59 il void work(){
    60     n=gi(); ans=du(n);
    61     printf("%lld %lld
    ",ans.phi,ans.mu);
    62     return;
    63 }
    64 
    65 int main(){
    66     File("du");
    67     sieve(); RG ll T=gi();
    68     while (T--) work();
    69     return 0;
    70 }
  • 相关阅读:
    Python三维绘图--Matplotlib colorbar生成
    Python三维绘图--Matplotlib
    VIM剪切板的使用
    三维点云网络PointNet——模型及代码分析
    ECCV2018--点云匹配
    hdu 1905 小数化分数2
    hdu 1755 A Number Puzzle
    hdu 1796 How many integers can you find
    hdu 1452 Happy 2004
    hdu 2837 Calculation
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6560324.html
Copyright © 2011-2022 走看看