bzoj4916神犇和蒟蒻 杜教筛

来源:互联网 发布:soulmate 知乎 编辑:程序博客网 时间:2024/06/06 07:46

题意:求sigma mu(i^2)和sigma phi(i^2)
..
这题以前刚学杜教筛的时候就想过没想到真的有人考出来了= =。
mu的那个明显怎么都是1.
phi的那个拆开就是phi(i)*i
线性求的时候顺便搞一下然后就和求sigma phi(i)没什么区别了。

#include<cstdio>#include<algorithm>#include<cstring>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fd(i,a,b) for(int i=a;i>=b;i--)using namespace std;const int N=1e6+5;typedef long long ll;const int mo=1e9+7;int n,niyuan2,niyuan6;int phi[N],a[N];int h[N];bool vis[N],bz[N];inline int pow(ll a,ll b){    int ans=1;    while (b)    {        if (b&1)ans=ans*a%mo;        a=a*a%mo;        b>>=1;    }    return ans;}inline int sum(int x){    return 1ll*x*(x+1)%mo*niyuan2%mo;}inline int calc(int x){    if (x<=N-5)return phi[x];    int t=n/x;    if (vis[t])return h[t];    int ans=1ll*(2*x+1)%mo*(x+1)%mo*x%mo*niyuan6%mo;    for(int l=2,r;l<=x;l=r+1)    {        r=x/(x/l);        ans=(ans+mo-1ll*(sum(r)-sum(l-1)+mo)%mo*calc(x/l)%mo)%mo;    }    vis[t]=1;    h[t]=ans;    return ans;}int main(){    niyuan2=pow(2,mo-2);    niyuan6=pow(6,mo-2);    scanf("%d",&n);    phi[1]=1;    int tot=0;    fo(i,2,N-5)    {        if (!bz[i])a[++tot]=i,phi[i]=1ll*(i-1)*i%mo;        fo(j,1,tot)        {            if (i*a[j]>N-5)break;            bz[i*a[j]]=1;            if (i%a[j]==0)            {                phi[i*a[j]]=1ll*phi[i]*a[j]%mo*a[j]%mo;                break;            }            else phi[i*a[j]]=1ll*phi[i]*phi[a[j]]%mo;        }    }    fo(i,1,N-5)phi[i]=(phi[i]+phi[i-1])%mo;    printf("1\n");    printf("%d\n",calc(n));}
原创粉丝点击