BZOJ2226: [Spoj 5971] LCMSum

死推

最后看了zky大爷的blog
常数垫底

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
using namespace std;
#define ll long long
char c;
inline void read(ll &a)
{a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}
inline void read(int &a)
{a=0;do c=getchar();while(c<'0'||c>'9');
while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}
const
  ll Maxn=1000001;
int Prime[Maxn];
ll Fai[Maxn];
bool Check[Maxn];
int tot;

int main()
{
    int T;
    int i,j,l;
    ll k;
    for(i=2;i<Maxn;i++)
    {
      if(!Check[i])Fai[i]=i-1,Prime[++tot]=i;
      for(j=1;j<=tot&&(k=Prime[j]*1ll*i)<Maxn;j++)
       {
          Check[k]=true;
          if(i%Prime[j]==0)
               {
                  Fai[k]=Prime[j]*Fai[i];
                  break;
               }
         Fai[k]=(Prime[j]-1)*Fai[i];
       }
    }
    Fai[1]=1;
    for(i=Maxn-1;i!=1;i--)
       Fai[i]*=i,Fai[i]>>=1;
    Fai[3]=3;
    Fai[2]=1;  
    read(T);
    while(T--)
    {
        int n;
        read(n);
        ll ans=0;
        int t=sqrt(n);
        for(int i=1;i<t;i++)
           if(n%i==0)
           {
              ans+=Fai[n/i];
              ans+=Fai[i];
           }
      if(t*t==n)ans+=Fai[t];
      else if(n%t==0)ans+=Fai[t],ans+=Fai[n/t];
      ans*=n;
      printf("%lld\n",ans);
    }
    return 0;
}

你可能感兴趣的:(BZOJ2226: [Spoj 5971] LCMSum)