码迷,mamicode.com
首页 > 其他好文 > 详细

3944: Sum[杜教筛]

时间:2017-05-14 23:36:45      阅读:295      评论:0      收藏:0      [点我收藏+]

标签:scanf   phi   code   style   source   for   http   prim   ble   

3944: Sum

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 3471  Solved: 946
[Submit][Status][Discuss]

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

HINT

 

Source

 

 
#include<cstdio>
#include<cstring>
typedef long long ll;
typedef unsigned int uint;
using namespace std;
const int N=5.4e6+5;
const int M=1e5+10;
ll mu[N],phi[N];
ll ans_mu[M],ans_phi[M];
bool vis_mu[M],vis_phi[M];
int n,m,T;ll ans1,ans2;
int tot,prime[N/3];bool check[N];
inline void sieve(){
    phi[1]=mu[1]=1;
    m=N-5;
//    m=pow(n,2.0/3.0);
    for(int i=2;i<=m;i++){
        if(!check[i]) prime[++tot]=i,mu[i]=-1,phi[i]=i-1;
        for(int j=1;j<=tot&&i*prime[j]<=m;j++){
            check[i*prime[j]]=1;
            if(!(i%prime[j])){mu[i*prime[j]]=0;phi[i*prime[j]]=phi[i]*prime[j];break;}
            else mu[i*prime[j]]=-mu[i],phi[i*prime[j]]=phi[i]*(prime[j]-1);
        }
    }
    for(int i=1;i<=m;i++) mu[i]+=mu[i-1],phi[i]+=phi[i-1];
}
inline ll get_phi(uint now){
    if(now<=m) return phi[now];
    int nn=n/now;
    if(vis_phi[nn]) return ans_phi[nn];
    vis_phi[nn]=1;
    ll sav=(ll)now*(now+1)>>1;
    for(uint i=2,pos;i<=now;i=pos+1){
        pos=now/(now/i);
        sav-=get_phi(now/i)*(pos-i+1);
    }
    return ans_phi[nn]=sav;
}
inline ll get_mu(uint now){
    if(now<=m) return mu[now];
    int nn=n/now;
    if(vis_mu[nn]) return ans_mu[nn];
    vis_mu[nn]=1;
    ll sav=1;
    for(uint i=2,pos;i<=now;i=pos+1){
        pos=now/(now/i);
        sav-=get_mu(now/i)*(pos-i+1);
    }
    return ans_mu[nn]=sav;
}
inline void clr(){
    memset(vis_mu,0,sizeof vis_mu);
    memset(vis_phi,0,sizeof vis_phi);
}
int main(){
    sieve();
    for(scanf("%d",&T);T--;clr()){
        scanf("%d",&n);
        ans1=get_phi(n);ans2=get_mu(n);
        printf("%lld %lld\n",ans1,ans2);
    }
    return 0;
}

 

3944: Sum[杜教筛]

标签:scanf   phi   code   style   source   for   http   prim   ble   

原文地址:http://www.cnblogs.com/shenben/p/6854363.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!