BZOJ 3944 杜教筛

原创 2018年04月17日 21:16:59

https://www.lydsy.com/JudgeOnline/problem.php?id=3944

第一次写杜教筛

被卡常数卡死

感觉还是比较神奇的

我终于理解了杜教筛的本质

哈哈哈

不过被卡常数了

没关系

不过学长的代码5秒钟切了

厉害

不过一向追求代码漂亮美观的我

感觉还是我写的代码比较漂亮

超时就超时吧

而且也不光我超时

感觉这题时限有点变态

随便从别的博客上找了几个别人的代码交上去

全他妈超时

超时代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e6;
int prime[N+10],tot;
int v[N+10];
ll phi[N+10];
ll miu[N+10];
map<ll,ll>_phi,_miu;

ll calcmiu(ll n){
    if(n<N)    return miu[n];
    if(_miu.count(n)) return _miu[n];
    ll x=2,ans=1;
    while(x<=n){
        ll y=n/(n/x);
        ans-=calcmiu(n/x)*(y-x+1);
        x=y+1;
    }
    return _miu[n]=ans;
}

ll calcphi(ll n){
    if(n<N) return phi[n];
    if(_phi.count(n)) return _phi[n];
    ll x=2,ans=n*(n+1)/2;
    while(x<=n){
        ll y=n/(n/x);
        ans-=calcphi(n/x)*(y-x+1);
        x=y+1;
    }
    return _phi[n]=ans;
}

int main(){
    for(int i=1;i<=N;++i) phi[i]=i;
    for(int i=2;i<=N;++i){
        if(phi[i]==i)
            for(int j=i;j<=N;j+=i)
                phi[j]=phi[j]/i*(i-1);
    }
    for(int i=1;i<=N;i++) miu[i]=1,v[i]=0;
    for(int i=2;i<=N;i++){
        if(v[i]) continue;
        miu[i] = -1;
        for(int j=2*i;j<=N;j+=i){
            v[j]=1;
            if((j/i)%i==0) miu[j]=0;
            else miu[j]*=-1;
        }
    }
    for(int i=2;i<=N;++i){
        phi[i]+=phi[i-1];
        miu[i]+=miu[i-1];
    }
    int T;
    scanf("%d",&T);
    while(T--){
        ll x;
        scanf("%lld",&x);
        cout<<calcphi(x)<<" "<<calcmiu(x)<<endl;
    }
}

学长的AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e6;
int prime[N+10],tot;
int v[N+10];
ll phi[N+10];
ll miu[N+10];
map<ll,ll>_phi,_miu;

ll calcmiu(ll n){
    if(n<N)    return miu[n];
    if(_miu.count(n)) return _miu[n];
    ll x=2,ans=1;
    while(x<=n){
        ll y=n/(n/x);
        ans-=calcmiu(n/x)*(y-x+1);
        x=y+1;
    }
    return _miu[n]=ans;
}

ll calcphi(ll n){
    if(n<N) return phi[n];
    if(_phi.count(n)) return _phi[n];
    ll x=2,ans=n*(n+1)/2;
    while(x<=n){
        ll y=n/(n/x);
        ans-=calcphi(n/x)*(y-x+1);
        x=y+1;
    }
    return _phi[n]=ans;
}

int main(){
    for(int i=1;i<=N;++i) phi[i]=i;
    for(int i=2;i<=N;++i){
        if(phi[i]==i)
            for(int j=i;j<=N;j+=i)
                phi[j]=phi[j]/i*(i-1);
    }
    for(int i=1;i<=N;i++) miu[i]=1,v[i]=0;
    for(int i=2;i<=N;i++){
        if(v[i]) continue;
        miu[i] = -1;
        for(int j=2*i;j<=N;j+=i){
            v[j]=1;
            if((j/i)%i==0) miu[j]=0;
            else miu[j]*=-1;
        }
    }
    for(int i=2;i<=N;++i){
        phi[i]+=phi[i-1];
        miu[i]+=miu[i-1];
    }
    int T;
    scanf("%d",&T);
    while(T--){
        ll x;
        scanf("%lld",&x);
        cout<<calcphi(x)<<" "<<calcmiu(x)<<endl;
    }
}

bzoj 3944: Sum 杜教筛

本来以为这种东西只能O(N)线性筛,但是大千世界,无(sang)奇(xin)不(bing)有(kuang),确实存在更快的算法。        省选的时候rzz讲这种东西在国内OI称为杜教筛,用来求数...
  • lych_cys
  • lych_cys
  • 2016-03-24 20:45:40
  • 5519

bzoj 3944: Sum (杜教筛)

题目描述传送门题目大意: ans1=∑ni=1φ(i)ans1=\sum_{i=1}^n \varphi(i), ans2=∑ni=1μ(i)ans2=\sum_{i=1}^n \mu(i) n...
  • clover_hxy
  • clover_hxy
  • 2017-02-28 15:36:54
  • 251

bzoj3944: Sum

杜教筛
  • FSAHFGSADHSAKNDAS
  • FSAHFGSADHSAKNDAS
  • 2017-03-31 21:02:21
  • 257

[BZOJ3944]SUM 杜教筛

题意求∑ni=1μ(i)\sum_{i=1}^{n}\mu(i)和∑ni=1ϕ(i)\sum_{i=1}^{n}\phi(i)1. ∑ni=1∑d|iμ(i)=1=∑ni=1∑⌊ni⌋j=1μ(j)...
  • Coldef
  • Coldef
  • 2017-01-24 15:44:02
  • 458

[杜教筛] BZOJ3944: Sum

题意给定n, 求∑ni=1ϕ(i)\sum_{i=1}^n \phi(i)和∑ni=1μ(i)\sum_{i=1}^n \mu(i) n≤231−1n \le 2^{31-1}题解假装做了一道新题 ...
  • CHHNZ
  • CHHNZ
  • 2017-07-04 12:12:26
  • 200

[BZOJ3944]Sum-杜教筛

Sum Description Input 一共T+1行 第1行为数据组数T(T 第2~T+1行每行一个非负整数N,代表一组询问 Output 一共T行,每行两个用空格分隔...
  • zlttttt
  • zlttttt
  • 2017-06-19 23:59:52
  • 224

BZOJ_P3944 Sum(数论+杜教筛)

BZOJ传送门Time Limit: 10 Sec Memory Limit: 128 MB Submit: 1108 Solved: 270 [Submit][Status][Discuss...
  • qq_18455665
  • qq_18455665
  • 2016-03-25 20:52:17
  • 739

[BZOJ4176]Lucas的数论(莫比乌斯反演+杜教筛)

题目描述传送门题解做约数个数和的时候有一个结论: d(nm)=∑i|n∑j|m[(i,j)=1]d(nm)=\sum\limits_{i|n}\sum\limits_{j|m}[(i,j)=1] ...
  • Clove_unique
  • Clove_unique
  • 2017-03-28 10:59:58
  • 1026

[杜教筛 约数个数前缀和] BZOJ 4176 Lucas的数论

吉丽博客传送门:http://jiruyi910387714.is-programmer.com/posts/195270.html 套用陈老师r老师等式后反演 #include #inc...
  • u014609452
  • u014609452
  • 2017-01-26 22:54:41
  • 800

bzoj 3930: [CQOI2015]选数 (杜教筛+反演)

题目描述传送门题目大意:从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案。求从区间[L,H]中选取N个整数,使其最大公约数刚好为K的选取方案有多少个。题解f(d)f(d)...
  • clover_hxy
  • clover_hxy
  • 2017-03-21 23:52:03
  • 272
收藏助手
不良信息举报
您举报文章:BZOJ 3944 杜教筛
举报原因:
原因补充:

(最多只允许输入30个字)