bzoj2705[SDOI2012] Longge的问题

来源:互联网 发布:农大网络教学综合平台 编辑:程序博客网 时间:2024/04/29 05:02

题目链接:bzoj2705
题目大意:
ni=1gcd(i,n)0<N232

题解:
数论,欧拉函数
dn的约数,有i=i×d
于是式子就可以写成

d|nd1idn,(id,n)=d1

d|nd1ind,(i,nd)=11

继而化为:
d|nd×ϕ(nd)

于是就O(n)枚举d,直接计算ϕ(nd),累加就好了。
额,先O(n)预处理出n的所有质因子吧,因为nd的质因子一定也在n的质因子中。

#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>using namespace std;typedef long long LL;LL cnt,pri[50];void get_pri(LL x,LL lim){    cnt=0;    for (LL i=2;x!=1 && i<=lim;i++)       if (x%i==0)      {          pri[++cnt]=i;          while (x%i==0) x/=i;      }    if (x!=1) pri[++cnt]=x;}LL phi(LL x){    LL ret=x;    for (LL i=1;i<=cnt;i++)      if (x%pri[i]==0) ret=ret*(pri[i]-1)/pri[i];    return ret;}int main(){    //freopen("a.in","r",stdin);    //freopen("a.out","w",stdout);    LL i,n,ans=0;    scanf("%lld",&n);    LL m=(LL)sqrt(n);    get_pri(n,m);    for (i=1;i<=m;i++) if (n%i==0)    {        LL x=i,y=n/i;        ans+=x*phi(y);        ans+=y*phi(x);    }    if (m*m==n) ans-=m*phi(m);    printf("%lld\n",ans);    return 0;}
0 0
原创粉丝点击