[杜教筛 莫比乌斯反演][BZOJ]4916: 神犇和蒟蒻(我)

4916: 神犇和蒟蒻
Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 326 Solved: 207
[Submit][Status][Discuss]
Description
很久很久以前,有一只神犇叫yzy;
很久很久之后,有一只蒟蒻叫lty;
Input
请你读入一个整数N;1<=N<=1E9,A、B模1E9+7;
Output
请你输出一个整数 A=Ni=1μ(i2);
请你输出一个整数 B=Ni=1φ(i2);
Sample Input
1
Sample Output
1
1
HINT
Source
By Monster_Yi

第一问就不说了,太显然了。
第二问:

φ(i)2=φ(i)i

f(i)=φ(i)i

id

(fid)(d)=i|df(i)ni=di|dφ(i)=d2

(fid)

i=1nd|if(d)id(nd)

j=1nf(j)S(nj)

f(1)S(n),

#include
#include
#define Mod 1000000007
#define N 1000000
int n,prim[100000],phi[N+5],cnt,S[N+5];
bool p[N+5];
std::map<int,int>a;
inline void pre(){
    phi[1]=1;
    for(int i=2;i<=N;++i){
        if(!p[i])prim[++cnt]=i,phi[i]=i-1;
        for(int j=1;j<=cnt&&i*prim[j]<=N;++j){
            p[i*prim[j]]=1;
            if(i%prim[j]==0){
                phi[i*prim[j]]=phi[i]*prim[j];
                break;
            }
            phi[i*prim[j]]=phi[i]*phi[prim[j]];
        }
    }
    for(int i=1;i<=N;++i)
        S[i]=(S[i-1]+1ll*phi[i]*i%Mod)%Mod;
}
int cal(int x){
    if(x<=N)return S[x];
    if(a.count(x))return a[x];
    int ans=1ll*(x+1)*(2*x+1)%Mod*333333336%Mod*x%Mod*500000004%Mod;
    for(int pos,i=2;i<=x;i=pos+1){
        pos=x/(x/i);
        ans=((ans-1ll*cal(x/i)*(pos+i)%Mod*(pos-i+1)%Mod*500000004%Mod)%Mod+Mod)%Mod;
    }
    return a[x]=ans;
}
int main(void){
    register int i;
    pre();
    scanf("%d",&n);
    puts("1");
    printf("%d",cal(n));
    return 0;
}

你可能感兴趣的:(BZOJ,杜教筛,莫比乌斯反演)